#!/bin/sh -- # A comment mentioning perl, to prevent perl from looping. Indented to work with bash. eval 'exec perl -S $0 ${1+"$@"}' if 0; $debug = 0; $devrandom = 0; $decimal = 0; $hex = 0; $mac = 0; $wep = 0; $skipchars = ''; $charlist = ''; $length = 8; $quiet = 0; $nmax = 0; $unique = 0; $ascii = 0; @args = @ARGV; chop($Program = `basename $0`); $Usage = <<"END"; $Program: generate a random password from a seed. Usage: $Program Options: -s Characters to not use. -c Use charlist characters only. -a "ascii", use [a-z0-9] only -A "ascii", use [A-z0-9] only -l Length of passwd (default: $length) -u Unique, do not repeat chars. -q,-n Quiet (no echo) when prompting for seed. -D Decimal digits only. -hex Hexidecimal digits only. -mac -hex and separate pairs of hex digits with ":" -N Use the first chars of the list. A-Za-z0-9~!@#$%^&*(){}[]_+-=|:;,./<>? -x use /dev/urandom for seeding. -d Debug mode. Notes: To get a random permutation of the alphabet do: rp -u -l 26 -N 26 END LOOP: while (@ARGV) { $_ = shift; CASE: { /^-s$/ && ($skipchars = shift, last CASE); /^-c$/ && ($charlist = shift, last CASE); /^-l$/ && ($length = shift, last CASE); /^-u$/ && ($unique = 1, last CASE); /^-a$/ && ($ascii = 1, last CASE); /^-A$/ && ($ascii = 2, last CASE); /^(-q|-n)$/ && ($quiet = 1, last CASE); /^-D$/ && ($decimal = 1, last CASE); /^-hex$/ && ($hex = 1, last CASE); /^-mac$/ && ($mac = 1, last CASE); /^-wep$/ && ($wep = 1, last CASE); /^-N$/ && ($nmax = shift, last CASE); /^-d$/ && ($debug = 1, last CASE); /^-x$/ && ($devrandom = 1, last CASE); /^--$/ && (last LOOP); # -- means end of switches /^-(-.*)$/ && (unshift(@ARGV, $1), last CASE); /^(-h|-help)$/ && ((print STDERR $Usage), exit 0, last CASE); if ( /^-(..+)$/ ) { # split bundled switches: local($y, $x) = ($1, ''); foreach $x (reverse(split(//, $y))) { unshift(@ARGV,"-$x") }; last CASE; } /^-/ && ((print STDERR "Invalid arg: $_\n$Usage"), exit 1, last CASE); unshift(@ARGV,$_); last LOOP; } } if ( $wep && ! $ENV{RP_WEP} ) { #easiest way... $ENV{RP_WEP} = 1; $args = join(' ', @args); $result = `$0 -hex -l 26 $args`; print STDOUT $result; $result =~ s/(....)/$1-/g; print STDOUT $result; exit 0; } if ( $mac && ! $ENV{RP_MAC} ) { #easiest way... $ENV{RP_MAC} = 1; $args = join(' ', @args); $result = `$0 -hex $args`; $result =~ s/(..)/$1:/g; $result =~ s/:$//; print STDOUT $result; exit 0; } &Initialize_List($skipchars); select(STDERR); $| = 1; select(STDOUT); $| = 1; if ( $length !~ /^\d+$/ ) { print STDERR "$Usage"; exit 1; } if ( $devrandom ) { my $rbytes; my $n = 8; my $file = ''; if ( open(RAN, "; chomp($s); $ARGV[0] = $s; } if ( $ARGV[0] eq '' ) { print STDERR "Please enter a seed number or phrase: "; if ( $quiet ) { $seed1 = &get_passwd(); print STDERR "Enter it again: "; $seed2 = &get_passwd(); if ( $seed1 ne $seed2 ) { print STDERR "Seeds differ. Exiting.\n"; exit 1; } $seed = $seed1; } else { chop($seed = ); } } else { $seed = join(' ', @ARGV); } if ( $seed =~ /^\d*$/ ) { if ( $seed eq '' ) { srand(); } else { srand($seed); } } else { chop($x = `echo "$seed" | sum | awk '{print \$1}' 2>/dev/null`); chop($y = $seed); $y = $seed if $y eq ''; chop($y = `echo "$y" | sum | awk '{print \$1}' 2>/dev/null`); if ( $x =~ /^\d+$/ && $y =~ /^\d+$/ ) { $z = $x * $y; # print STDERR "(using seed $z)\n\n"; srand($z); } else { # print STDERR "(not using seed $x * $y)\n\n"; srand($seed); } } if ( $unique && $length > $Size ) { print STDERR "length too long: $length > $Size, resetting length to $Size\n"; $length = $Size; } for ($i = 0; $i < $length; $i++) { $R = int(rand($Size)); if ( $unique && $Hit{$R} ) { $i--; next; } $Hit{$R}++; print STDOUT $List[$R]; $f = int(10*rand()) + 1; for ( $j=0; $j < $f; $j++) { $R = rand(); # print STDERR "." if $debug; } } print STDOUT "\n"; exit 0; sub Initialize_List { local($skip) = @_; local(@List0, $item); if ( $charlist ne '' ) { @List0 = split(//, $charlist); } elsif ( $ascii == 1 ) { @List0 = qw ' a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 0 '; } elsif ( $ascii == 2 ) { @List0 = qw ' A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 0 '; } elsif ( $decimal ) { @List0 = qw ' 1 2 3 4 5 6 7 8 9 0 '; } elsif ( $hex ) { @List0 = qw ' 1 2 3 4 5 6 7 8 9 0 a b c d e f '; } else { @List0 = qw ' A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 0 ~ ! @ # $ % ^ & * ( ) { } [ ] _ + - = | : ; , . / < > ? '; } $skip =~ s/(\W)/\\$1/g; #print STDERR "skip: $skip\n"; $cnt = 0; foreach $item (@List0) { $cnt++; if ( $nmax > 0 && $cnt > $nmax ) { # print STDERR "last item is: $item\n"; last; } next if $skip ne '' && $item =~ /[$skip]/; push (@List, $item); } $Size = @List; if ( $debug ) { for ($i = 0; $i < $Size; $i++) { print STDERR "$i: $List[$i]\n"; } } } sub get_passwd { # prompt for a password w/o echoing. local($input) = ''; system("stty -echo"); chop($input=); print "\n"; system("stty echo"); return $input; } __END__