Getopt::Long::Configure ("bundling");
####
* No space between function name and its opening parenthesis.
####
## PARSE AND SET COMMAND-LINE OPTIONS
## -----------------------------------------------------
####
my %flags=('symbols', 0, 'numbers', 0, 'uppercase', 0, 'lowercase', 0, 'confusable', 0, 'help', 0, 'qty', 1);
####
my %flags=map {$_ => 0 }
qw/symbols numbers uppercase lowercase confusable help);
$flags{qty}=1;
####
my $pwdchars = join( '', map {chr} ( 0x21 .. 0x7e ));
$pwdchars =~ s/\d+// if ( $flags{numbers} );
$pwdchars =~ s/[A-Z]+// if ( $flags{uppercase} );
$pwdchars =~ s/[a-z]+// if ( $flags{lowercase} );
$pwdchars =~ s/[_\W]+//g if ( $flags{symbols} );
$pwdchars =~ tr/1Il0O//d if ( $flags{confusable} );
####
my $pwdchars = join '', map chr, 0x21 .. 0x7e;
for ($pwdchars) {
s/\d+// if $flags{numbers};
s/[A-Z]+// if $flags{uppercase};
s/[a-z]+// if $flags{lowercase};
s/[_\W]+//g if $flags{symbols};
tr/1Il0O//d if $flags{confusable};
}
####
# If user triggered the --help option flag, display and exit
if ($flags{help}) {
&DisplayUsage();
exit();
}
####
print(USAGE), exit if $flags{help};
####
my $kill=0; # flag to stop the script if input is invalid (or --help is used)
my @errmsg; # error message descriptions
####
if ($flags{qty} == 0 || $flags{qty} < 0) {
$flags{qty}=1;
}
####
$flags{qty}=1 if $flags{qty} <= 0;
####
$flags{qty}=1 unless $flags{qty} > 0;
####
$flags{qty}=1 unless $flags{qty} >= 1;
####
if ( length($pwdchars) == 0) {
####
if ($pwdchars) {
####
# Check that user has passed only 1 argument (LENGTH) other than options flags, warn user, kill script
if ($#ARGV > 0 || $#ARGV < 0) {
####
unless (@ARGV==1) {
####
# Check for only numeric input in LENGTH argument, warn user, kill script
if ($ARGV[0] !~ /^[0-9]+$/) {
####
# If any of the above validation tests triggered the $kill flag...
if ($kill == 1) {
print "\n** GENPASS ERROR ---------------------------------------------------------";
print "\n** ".@errmsg." Error(s) found"; # display number of errors
foreach my $err (@errmsg) { # display error messages
print "\n".$err;
}
print "\n**\n** Type genpass --help for command usage\n";
print "** -----------------------------------------------------------------------\n\n";
exit(); # exit script
}
####
for ( 0..$pwdlen-1 ) {
$pwd .= substr( $pwdchars, rand( $limit ), 1 );
}
####
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
sub collecterr;
sub chkerr ();
sub USAGE ();
Getopt::Long::Configure('bundling');
my %flags=map {$_ => 0 } qw/symbols numbers uppercase lowercase confusable help/;
$flags{qty}=1;
GetOptions( 's|S|symbols' => \$flags{symbols},
'n|N|numbers' => \$flags{numbers},
'u|U|uppercase' => \$flags{uppercase},
'l|L|lowercase' => \$flags{lowercase},
'c|C|confusable' => \$flags{confusable},
'q|Q:i' => \$flags{qty},
'help' => \$flags{help} );
print(USAGE), exit if $flags{help};
$flags{qty}=1 if $flags{qty} <= 0;
my @pwdchars=do {
local $_=join '', map chr, 0x21..0x7e;
s/\d+// if $flags{numbers};
s/[A-Z]+// if $flags{uppercase};
s/[a-z]+// if $flags{lowercase};
s/[_\W]+//g if $flags{symbols};
tr/1Il0O//d if $flags{confusable};
no warnings 'uninitialized';
/./g;
};
collecterr "0x1: At least 1 character-type must be included" unless @pwdchars;
collecterr "0x2: Incorrect number of arguments passed" unless @ARGV==1;
my $len=shift;
if (defined $len) {
collecterr "0x3: Invalid input. LENGTH argument must be a numeric value"
unless $len =~ /^[0-9]+$/;
}
chkerr;
print +(map $pwdchars[rand @pwdchars], 1..$len), "\n"
for 1..$flags{qty};
# -- subs --
{
my @errmsg;
sub collecterr { push @errmsg, @_ }
sub chkerr () {
return unless @errmsg;
my $pre="\n**";
die "$pre GENPASS ERROR ", "-" x 56,
"$pre " . @errmsg . " Error(s) found",
(map "$pre $_", @errmsg),
"$pre ", "-" x 71, USAGE;
}
}
sub USAGE () {
<<" USAGE";
Usage: genpass [-OPTIONS] LENGTH
Generate secure passwords LENGTH characters long.
-s, --symbols\t\tExclude symbols.
-n, --numbers\t\tExclude numbers.
-u, --uppercase\t\tExclude uppercase letters.
-l, --lowercase\t\tExclude lowercase letters.
-c, --confusable\tExclude confusable characters like: l,I,1,0,O
-q(X)\t\t\tCreate X number of passwords.
--help\t\t\tDisplay this usage screen.
Report bugs, comments, and questions to jbrown_home\@yahoo.ca
USAGE
}
__END__
####
genpass -snul 10
genpass
genpass abc
genpass -snul
genpass abc def
genpass -snul abc
genpass -snul abc def
####
C:\temp>genpass -scq10 10
v36Bhe2mE4
GULShqLdFi
XeduriA83S
h77kYA6Qdf
qLkXNB8fqo
wBrFaSr7cZ
EfcZNgtvmD
2ZqYMq6NS4
jRUhKdfs46
mV2qZJVnWb