Thank you everyone for your comments, critiques and suggestions. I have looked over my code and made changes where they made sense to me.

Some of the suggestions left me with nothing to do but cut and paste the code in the reply (see the GenPass function, the use of a flags hash, the heredocs tip.) I did, of course, look over what the code did and saw why it was a better way, because unlike some who post questions on forums, I have no problem doing the work, I'm not looking for other people to do the work for me. I am here to learn. I just want that to be clear.

I think the biggest efficiency tip for me was putting all the characters in a string, then using regex to pull excluded types out of the string. Not only did that alone cut nearly 50 lines of code from the script, but it also cut out all the extraoneous loops that tested "dead" value characters between 33 and 126.

One thing that I may look into is incorporating a switch to handle (or offer) different character sets.

Again, thank all you monks, and here I post the updated version. Cheers:

#!/usr/bin/perl use strict; use warnings; use Getopt::Long; Getopt::Long::Configure ("bundling"); ## PARSE AND SET COMMAND-LINE OPTIONS ## ----------------------------------------------------- my %flags=('symbols', 0, 'numbers', 0, 'uppercase', 0, 'lowercase', 0, + 'confusable', 0, 'help', 0, '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}, ); # Set password characters, excluding those flagged on the command-line 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} ); # If user triggered the --help option flag, display and exit if ($flags{help}) { &DisplayUsage(); exit(); } ## START VALIDATE INPUT ## ----------------------------------------------------- my $kill=0; # flag to stop the script if input is invalid (or - +-help is used) my @errmsg; # error message descriptions # If -q option was used to set a quantity of passwords, make sure it c +ontains at # least a value of 1 so that a password can be generated if ($flags{qty} == 0 || $flags{qty} < 0) { $flags{qty}=1; } # Check that user hasn't excluded all character-types, warn user, kill + script if ( length($pwdchars) == 0) { push @errmsg, "** 0x1: At least 1 character-type must be included" +; $kill=1; } # Check that user has passed only 1 argument (LENGTH) other than optio +ns flags, warn user, kill script if ($#ARGV > 0 || $#ARGV < 0) { push @errmsg, "** 0x2: Incorrect number of arguments passed"; $kill=1; } # Check for only numeric input in LENGTH argument, warn user, kill scr +ipt if ($ARGV[0] !~ /^[0-9]+$/) { push @errmsg, "** 0x3: Invalid input. LENGTH argument must be +a numeric value"; $kill=1; } # 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 } ## END VALIDATE INPUT ## START MAIN SCRIPT ## ----------------------------------------------------- # From 1 to qty for ( 1..$flags{qty} ) { print &GenPass( $ARGV[0] )."\n"; } exit(); ## END MAIN SCRIPT ## FUNCTION DEFINITIONS ## ----------------------------------------------------- sub GenPass() { my ($pwdlen) = @_; my $limit = length( $pwdchars ); my $pwd = ''; for ( 0..$pwdlen-1 ) { $pwd .= substr( $pwdchars, rand( $limit ), 1 ); } return $pwd; } # use Here-Documents to display usage text sub DisplayUsage { print <<" 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__

In reply to Re: genpass Password Generator by Anonymous Monk
in thread genpass Password Generator by munkyeetr

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.