#!/usr/bin/env bash set -eo pipefail # Ref: https://theworld.com/~reinhold/diceware.html # Ref: https://www.eff.org/deeplinks/2016/07/new-wordlists-random-passphrases if [[ ! -x "$(command -v curl)" ]]; then echo "Please install curl" exit 1 fi if [[ ! -x "$(command -v shuf)" ]]; then echo "Please install coreutils" exit 1 fi if [[ ! -x "$(command -v gum)" ]]; then echo "Please install https://github.com/charmbracelet/gum" exit 1 fi opt_five='five dice, long wordlist' url_five='https://www.eff.org/files/2016/07/18/eff_large_wordlist.txt' dst_five='eff_large_wordlist.txt' opt_four_short='four dice, short wordlist' url_four_short='https://www.eff.org/files/2016/09/08/eff_short_wordlist_1.txt' dst_four_short='eff_short_wordlist_1.txt' opt_four_long='four dice, long wordlist' url_four_long='https://www.eff.org/files/2016/09/08/eff_short_wordlist_2_0.txt' dst_four_long='eff_short_wordlist_2_0.txt' echo 'Which wordlist to use?' WORDLIST=$(gum choose "$opt_five" "$opt_four_short" "$opt_four_long") echo ">> $WORDLIST" echo 'How many words to pick?' COUNT=$(gum input --value='4') echo ">> $COUNT" echo 'Which word separator to use?' SEPARATOR=$(gum choose 'dash' 'space' 'underscore') echo ">> $SEPARATOR" CACHE_DIR="${HOME}/.diceware" if [[ ! -d "$CACHE_DIR" ]]; then mkdir "$CACHE_DIR" fi word_src="$url_five" word_file="${dst_five}" if [[ "$WORDLIST" == "$opt_four_short" ]]; then word_src="$url_four_short" word_file="$dst_four_short" fi if [[ "$WORDLIST" == "$opt_four_long" ]]; then word_src="$url_four_long" word_file="$dst_four_long" fi word_file="${CACHE_DIR}/${word_file}" if [[ ! -f "$word_file" ]]; then curl -sSf "$word_src" -o "$word_file" fi dice='4' if [[ "$WORDLIST" == "$opt_five" ]]; then dice='5' fi separator=' ' if [[ "$SEPARATOR" == "dash" ]]; then separator='-' elif [[ "$SEPARATOR" == "underscore" ]]; then separator='_' fi phrase='' for i in $(seq "$COUNT"); do group='' for j in $(seq "$dice"); do roll=$(shuf -i 1-6 -n 1 --random-source=/dev/random) if [[ -z "$group" ]]; then group="$roll" else group="${group}${roll}" fi done word=$(grep "$group" "$word_file" | awk '{print $2}') if [[ -z "$phrase" ]]; then phrase="$word" else phrase="${phrase}${separator}${word}" fi done gum style \ --border double --align center \ --margin '1 2' --padding '2 4' \ "$phrase"