Skip to content

Instantly share code, notes, and snippets.

@atoponce
Last active November 5, 2023 17:08
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save atoponce/b95601f74694f3238dae0b95aef0a647 to your computer and use it in GitHub Desktop.
Save atoponce/b95601f74694f3238dae0b95aef0a647 to your computer and use it in GitHub Desktop.
Three password generators in ZSH

Each generator yields 128-bit security passwords. Each generator can take an optional numeric password to generate that many passwords. They should be placed in your ~/.zshrc. They are not portable across other shells.

gen-monkey-pass generates visually unambiguous random meaningless strings using Crockford's base32. Requires only ZSH:

% gen-monkey-pass 
9cws91tjck93f0xymjn33cjt7m
% gen-monkey-pass 3
2p9a0y3pkg3tvmdn2yqzv8qnb9
3n5wzr0ag4tmwwf5hfkb5157tj
5a46mdq46rx2hznsr88srnj8tg

gen-xkcd-pass generates passphrases from your /usr/share/dict/words file prepended with a digit showing the number of words in the passphrase to adhere to password security requirements that require digits. Requires grep(1), GNU coreutils (or appropriate for your system), wamerican (or appropriate for your system) and ZSH:

% gen-xkcd-pass 
9-aright-erg-tubes-Cory-snail-Urdu-sudden-where-powwow
% gen-xkcd-pass 3
9-larded-baud-robes-corps-passel-Enif-Brutus-wiper-starve
9-curled-faint-Aryan-motor-log-Asiago-earn-how-agony

gen-apple-pass generates a pronounceable pseudoword of the "cvccvc" consonant/vowel syntax. Each pseudoword has exactly 1 digit placed at the edge of a word and exactly 1 capital letter to satisfy password security requirements. Requires GNU coreutils (or appropriate for your system) and ZSH:

% gen-apple-pass 
pocfol-hevtE0-baptuh-dycjiw-kylhid-biwsoh
% gen-apple-pass 3
musfoq-towsah-3ukkyq-jumnuc-handAk-kapwin
tajbob-pancyg-xotnum-1etxir-Felsys-fapxav
lelmuj-vigzow-vectys-sirbeg-2ocxaq-vYcpof
gen-apple-pass() {
# Generates a pseudoword with at least 128 bits entropy
autoload -U regexp-replace
[[ $1 =~ '^[0-9]+$' ]] && local num=$1 || local num=1
local c="$(tr -cd b-df-hj-np-tv-xz < /dev/urandom | head -c $((24*$num)))"
local v="$(tr -cd aeiouy < /dev/urandom | head -c $((12*$num)))"
local d="$(tr -cd 0-9 < /dev/urandom | head -c $num)"
local p="$(tr -cd 056bchinotuz < /dev/urandom | head -c $num)"
typeset -A base36=(0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 a 10 b 11 c 12 d 13 e 14 f 15 g 16 h 17 i 18
j 19 k 20 l 21 m 22 n 23 o 24 p 25 q 26 r 27 s 28 t 29 u 30 v 31 w 32 x 33 y 34 z 35)
for i in {1.."$num"}; do
unset pseudo
for j in {1..12}; do
# uniformly iterating through the large $c and $v strings for each $i and each $j
pseudo="${pseudo}${c:$((-26+24*$i+2*$j)):1}${v:$((-13+12*$i+$j)):1}${c:$((-25+24*$i+2*$j)):1}"
done
local digit_pos=$base36[$p[$i]]
local char_pos=$digit_pos
while [[ "$digit_pos" -eq "$char_pos" ]]; do
char_pos=$base36[$(tr -cd 0-9a-z < /dev/urandom | head -c 1)]
done
regexp-replace pseudo "^(.{$digit_pos}).(.*)$" '${match[1]}${d[$i]}${match[2]}'
regexp-replace pseudo "^(.{$char_pos})(.)(.*)$" '${match[1]}${(U)match[2]}${match[3]}'
regexp-replace pseudo '^(.{6})(.{6})(.{6})(.{6})(.{6})(.{6})$' \
'${match[1]}-${match[2]}-${match[3]}-${match[4]}-${match[5]}-${match[6]}'
printf "${pseudo}\n"
done
}
gen-monkey-pass() {
# Generates an unambiguous password with at least 128 bits entropy
# Uses Crockford's base32
[[ $1 =~ '^[0-9]+$' ]] && local num=$1 || local num=1
local pass=$(tr -cd '0-9a-hjkmnp-tv-z' < /dev/urandom | head -c $((26*$num)))
for i in {1.."$num"}; do
printf "${pass:$((26*($i-1))):26}\n" # add newline
done
}
gen-xkcd-pass() {
# Generates a passphrase with at least 128 bits entropy
zmodload zsh/mathfunc
[[ $1 =~ '^[0-9]+$' ]] && local num=$1 || local num=1
local dict=$(grep -E '^[a-zA-Z]{,6}$' /usr/share/dict/words)
local words=$((int(ceil(128*log(2)/log(${(w)#dict})))))
for i in {1.."$num"}; do
printf "$words-"
printf "$dict" | shuf --random-source=/dev/urandom -n "$words" | paste -sd '-'
done
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment