diff options
-rwxr-xr-x | makepass.zsh | 84 |
1 files changed, 51 insertions, 33 deletions
diff --git a/makepass.zsh b/makepass.zsh index c337939..caa8dca 100755 --- a/makepass.zsh +++ b/makepass.zsh @@ -56,9 +56,12 @@ ENVIRONMENT characters long. MAKEPASS_NUMBER - The default number of passwords from each group to output. By default - 10 normal passwords, six special passwords, and six passphrases, are - printed. Valid values are 1-255. + The number of passwords from each group to output. This formula is + used: + n normal passwords + n / 3 * 2 + 1 special passwords + n / 2 passphrases + Where n is 10 by default. Valid values for n are 1-255. MAKEPASS_NORMAL String of characters from which to generate "normal" passwords. @@ -90,10 +93,8 @@ AUTHOR return 0 } - - # Create random passphrase -function randphrase() { +function passphrase() { setopt localoptions rematch_pcre local -i len=${1:-8} local prestring string @@ -118,9 +119,9 @@ function randphrase() { # Function to create random strings function randstring() { - # Default is a number between 8 and 44 - local -i len=$(( $1 ? $1 : RANDOM % (44 - 8 + 1) + 8 )) - local chars=${2:-$alnum} + # Default is a number in the range <RANGE_MIN-RANGE_MAX> + local -i len=$(( $1 ? $1 : RANDOM % (RANGE_MAX - RANGE_MIN + 1) + RANGE_MIN )) + local chars=${2:-$ALNUM} local flc=${3:-} # first-last-character local string repeat $len string+=$chars[$((RANDOM % $#chars + 1))] @@ -143,21 +144,29 @@ function die() { exit 1 } -# makepass-function. This is where the magic happens -function makepass() { +# main-function. This is where the magic happens +function main() { setopt localoptions - local lower='abcdefghijklmnopqrstuvwxyz' - local upper='ABCDEFGHIJKLMNOPQRSTUVWXYZ' - local digit='0123456789' - local other='!#$%&/()=?+-_,.;:<>[]{}|\@*' - local alpha=${lower}${upper} - local alnum=${alpha}${digit} - local every=${alnum}${other} - - local -i length=${MAKEPASS_LENGTH:-0} - local normal=${MAKEPASS_NORMAL:-$alnum'-_'} - local special=${MAKEPASS_SPECIAL:-$every} - local wordlist=${MAKEPASS_WORDLIST:-/usr/share/dict/words} + + integer MAX_LENGTH=255 # max length of passwords + integer RANGE_MAX=42 # max length when using random length + integer RANGE_MIN=8 # min length when using random length + integer PASS_WORDS=8 # number of words in passphrases + readonly MAX_LENGTH RANGE_MAX RANGE_MIN PASS_WORDS + + readonly LOWER='abcdefghijklmnopqrstuvwxyz' + readonly UPPER='ABCDEFGHIJKLMNOPQRSTUVWXYZ' + readonly DIGIT='0123456789' + readonly OTHER='!#$%&/()=?+-_,.;:<>[]{}|\@*' + readonly ALPHA=${LOWER}${UPPER} + readonly ALNUM=${ALPHA}${DIGIT} + readonly EVERY=${ALNUM}${OTHER} + + integer length=${MAKEPASS_LENGTH:-0} # length of passwords + integer number=${MAKEPASS_NUMBER:-10} # number of passwords + local normal=${MAKEPASS_NORMAL:-$ALNUM'-_'} + local special=${MAKEPASS_SPECIAL:-$EVERY} + local wordlist=${MAKEPASS_WORDLIST:-/usr/share/dict/words} # Seed $RANDOM with a random 32bit integer from /dev/urandom local r4 # will be filled with 4 random bytes from /dev/urandom @@ -180,39 +189,49 @@ function makepass() { die "Unknown argument";; esac done - shift $((OPTIND - 1)) + + # # Some error-checking + # + # We only take one argument in addition to the optargs (( ARGC > 1 )) && die "only one argument" + # if there is an argument, set it to $length [[ -n $1 ]] && length=$1 + + # Check $length and $number [[ $length = <0-255> ]] || die "length must be a number between 0 and 255" + [[ $number = <1-255> ]] || die "number-argument must be between 1 and 255" + + # # Print! # + # Normal passwords print "Normal passwords:" - print -c -- $(repeat 10 { randstring $length $normal; : $RANDOM }) + print -c -- $(repeat $number { randstring $length $normal; : $RANDOM }) : $RANDOM print # Passowrds with special characters print "Passwords with special characters:" - print -c -- $(repeat 6 { randstring $length $special $alpha; : $RANDOM }) + print -c -- $(repeat $((number/3*2+1)) { randstring $length $special $ALPHA; : $RANDOM }) : $RANDOM # Passphrases - but only if a wordlist is available - if [[ -r $wordlist ]]; then + if [[ -r $wordlist ]] && ((number / 2 > 0)); then print print "Passphrases:" - local -a words=(${(f)"$(<"$wordlist")"}) - repeat 6 randphrase + local -a words=(${(f)"$(<$wordlist)"}) + repeat $((number / 2)) passphrase fi } -makepass "${@:-}" +main "${@:-}" # Last time I redid this script I benchmarked some ways to generate random # strings. Here's the results: @@ -230,12 +249,11 @@ makepass "${@:-}" # 24.13s user 11.38s system 120% cpu 29.442 total # # string-addition with randint32()-function to get random 32bit integer from /dev/urandom -# % time (repeat 10000 { string='';repeat 20 string+=$alpha[$((randint32() % $#alpha + 1))] }) +# % time (repeat 10000 { string='';repeat 20 string+=$ALPHA[$((randint32() % $#ALPHA + 1))] }) # 8.17s user 3.28s system 99% cpu 11.475 total # # string-addition and $RANDOM -# % time (repeat 10000 { string='';repeat 20 string+=$alpha[$((RANDOM % $#alpha + 1))] } ) +# % time (repeat 10000 { string='';repeat 20 string+=$ALPHA[$((RANDOM % $#ALPHA + 1))] } ) # 0.74s user 0.00s system 99% cpu 0.741 total - ## END OF FILE ################################################################# |