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