#!/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__