Skip to content

Instantly share code, notes, and snippets.

@imaami
Last active May 18, 2019 20:03
Show Gist options
  • Save imaami/29c54bcbf481ba6c2004e22ff74224db to your computer and use it in GitHub Desktop.
Save imaami/29c54bcbf481ba6c2004e22ff74224db to your computer and use it in GitHub Desktop.
#!/bin/bash
num_words="$1"
orig_dict="$2"
dict_file=''
ret_value=0
max_word_len=9 # Exclude words longer than this
phrase_count=6 # How many passphrases to generate
(( num_words > 0 )) || (( num_words = 4 ))
[[ "$orig_dict" ]] || {
for sfx in '-small' '' '-large' '-huge' '-insane'; do
orig_dict="/usr/share/dict/american-english$sfx"
[[ ! -e "$orig_dict" ]] || break
orig_dict="/usr/share/dict/british-english$sfx"
[[ ! -e "$orig_dict" ]] || break
done
}
[[ -e "$orig_dict" ]] || {
echo 'No dictionary found' >&2
exit 1
}
dict_file="$(mktemp -p /dev/shm tmp-dict.XXXXXXXX)"
LANG=C egrep "^[[:alpha:]]{1,$((max_word_len))}$" "$orig_dict" > "$dict_file"
dict_size=$(wc -l "$dict_file" 2>/dev/null | cut -d' ' -f1)
if (( dict_size < 1 )); then
echo 'Empty dictionary' >&2
ret_value=1
else
if [[ -t 2 ]]; then
B='\e[32m'; L='\e[34m'; E='\e[33m'; R='\e[36m'; N='\e[0m'
else
B=''; L=''; E=''; R=''; N=''
fi
echo -e "$B[${L}num_words$E=$R$num_words$B]$N" >&2
echo -e "$B[${L}dict_size$E=$R$dict_size$B]$N" >&2
echo -e "$B[${L}entropy$E=$R$(bc -l <<< "scale=3; l($dict_size^$num_words)/l(2)")$B]$N" >&2
rand_mask='0xffffffff'
while (( rand_mask >= dict_size )); do
(( m = rand_mask >> 1 ))
(( m >= dict_size )) || break
rand_mask=$(printf '0x%x\n' "$m")
done
for (( i = 0; i < 6; i++ )); do
(( n = num_words ))
while (( n > 0 )); do
R=$(od -N4 -tu4 -An -w4 /dev/urandom | tr -d ' ')
R=$((R & rand_mask))
(( R < dict_size )) || continue
W=$(tail -n+$((R+1)) "$dict_file" | head -1)
W="$(tr '[:lower:]' '[:upper:]' <<< ${W:0:1})${W:1}"
echo -n "$W"
(( n-- ))
done
echo
done
fi
rm -f "$dict_file"
exit $ret_value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment