#!/usr/bin/perl use strict; use warnings; my @chars = ( "a" .. "k", "m","n", "p" .. "z"); my @upchars = ("A".."N","P".."Z"); # <-- NOTE: "P..Z" -> "P".."Z" my @nona = qw(! @ $ % & ( ) + = { } [ ] < > ~); my @nums = (0 .. 9); my $lc = \@chars; my $uc = \@upchars; my $na = \@nona; my $nu = \@nums; my @types = ($lc, $uc, $na, $nu); # compact: my @types = (\@chars, \@upchars, ... my $a = join("", @{$types[3]}[ map { rand @{$types[3]} } ( 1 .. 4 ) ]); $a .= join("", @{$types[2]}[ map { rand @{$types[2]} } ( 1 .. 4 ) ]); $a .= join("", @{$types[1]}[ map { rand @{$types[1]} } ( 1 .. 4 ) ]); $a .= join("", @{$types[0]}[ map { rand @{$types[0]} } ( 1 .. 4 ) ]); # ^--deref/arrayslice ^-- deref for number of elements # nobody complained about using '$a' yet, so I don't do either ;-) print "My selection is $a \n"; # you should shuffle and shorten the result exit; __DATA__ My selection is 0548)~}+QRVKzkkt My selection is 7922&)(&AAZZwiaw My selection is 5263+!@>VXXBaezt