#!/usr/bin/perl use strict; use warnings; use Getopt::Long; use Pod::Usage; ## Character sets for passwords my $vowels = [qw( a e i o u )]; my $letters = [ 'a' .. 'z' ]; my $numbers = [ '0' .. '9' ]; my $symbols = [qw( ` ~ ! @ $ % ^ & * _ - + = . < > ; : ' " )]; my $consonants = [ grep { not /aeiou/ } @$letters ]; my $printable = [ grep /[[:graph:]]/, map chr, 0 .. 255 ]; ## Return a random element of the arrayref sub pick { my @set = @{ $_[0] }; return $set[ int rand @set ]; } ## Generate a random password of requested length sub generate_password { my ( $length, $pattern ) = @_; my ( $pass, $set ) = ( "", $printable ); ## Follow the pattern foreach ( split //, $pattern ) { /p/i and $set = $printable; /v/i and $set = $vowels; /c/i and $set = $consonants; /l/i and $set = $letters; /n/i and $set = $numbers; /s/i and $set = $symbols; ## Uppercase => always, lowercase => half /[[:upper:]]/ and $pass .= pick $set; /[[:lower:]]/ and $pass .= pick $set if rand >= 0.5; } ## Pad out, using last $set, where necessary $pass .= join "", @{$set}[ map int rand @{$set}, 1 .. ( $length - length $pass ) ]; return $pass; } ## Option handling my %opt = ( man => "0", help => "0", length => 8, pattern => "CVCNCVCN" ); GetOptions( \%opt, "man", "help", "length=i", "pattern=s" ) or pod2usage(0); $opt{man} and pod2usage( -exitval => 0, -verbose => 2 ); $opt{help} and pod2usage(0); $opt{pattern} =~ /^[pvclns]+$/i or warn "$0: extra characters in pattern.\n"; ## Actually do to the work printf "%s\n", generate_password( $opt{length}, $opt{pattern} ); =head1 NAME generate-random-password =head1 SYNOPSIS generate-random-password [ --length=N ] [ --pattern=string ] generate-random-password [ --man | --help ] =head1 DESCRIPTION B uses perl's internal rand() function to generate random passwords. =head1 OPTIONS =over 8 =item B<--length=N> Produce a random password with at least this number of characters. The default is eight (8). =item B<--pattern=string> The characters in the pattern string have the following meanings. =over 8 =item B

printable =item B vowels =item B consonants =item B letters =item B numbers =item B symbols =back For each upper case character, an element from the set will be used. For lower case characters, an element is used half of the time. Where necessary, the password is padded out using the last set selected. See the B for more information. The default is "CVCNCVCN", which matches the default length. =item B<--man> Print the manual page and exit. =item B<--help> Print a brief help message and exit. =back =head1 EXAMPLES ./generate-random-password --length 10 --pattern CVCcNsCVCc wut6lovfxt ./generate-random-password --length 10 --pattern C dqgbpmgxmh ./generate-random-password --length 10 --pattern N 3650943126 ./generate-random-password --length 10 --pattern ns 7';&>_"=+~ ./generate-random-password --length 10 --pattern p ;DQ4`fSPLR =head1 AUTHOR Mark Suter EFE =head1 VERSION $Id: generate-random-password,v 1.10 2008/05/27 03:05:14 suter Exp suter $ =cut