http://xkcd.com/936/

Not worth creating a project for, and it might be interesting to see what changes people would make.

Non-standard dependencies:

  • words, for the dictionary
  • zsh (this will probably work just fine with bash, though, too)
#!/usr/bin/zsh
# Author: @[email protected]
# 2025-02-23

final=(xargs echo)
count=6
while getopts d opt; do
	case $opt in
		d)
			final=(tr 'A-Z' 'a-z')
			;;
		*)
			printf "Password generator based on the correcthorse algorithm from http://xkcd.com/936//n/n"
			printf "USAGE: %s [-d] [#]\n" "$0"
			printf " -d  make the result all lower case; otherwise, each word will be capitalized.\n"
			printf " #   the number of words to include. Defaults to 6."
			exit 1
			;;
	esac
done
shift $(($OPTIND - 1))
[[ $# -gt 0 ]] && count=$*

shuf -n $((count * 2)) /usr/share/dict/american-english | \
	sed 's/'"'"'.*//; s/^\(\w\)/\U\1/' | \
	sort | uniq | shuf -n $count | xargs echo | \
	tr -d ' ' | $final

What’s going on here:

Nearly 30% of the American dictionary (34,242) are words with apostrophes. They could be left in to help satisfy password requirements that demand “special characters,” but correcthorse isn’t an algorithm that handles idiot “password best practices” well anyway. So, since every word with an apostrophe has a pair word without one, we pull 2·N words to make sure we have enough. Then we strip out the plural/possessives and capitalize every word. Then we remove duplicates and select our N words from the result. Finally, we compact that into a space-less string of words, and if the user passed the -d option, we downcase the entire thing.

Without the user options, this really could be a 1-liner; that’s how it started:

alias pony="shuf -n 12 /usr/share/dict/american-english | sed 's/'\"'\"'.*//; s/^\(\w\)/\U\1/' | sort | uniq | shuf -n 6 | xargs echo | tr -d ' '"
  • some_guy@lemmy.sdf.org
    link
    fedilink
    arrow-up
    2
    ·
    5 days ago

    I opened this in a browser tab on my phone so that I can remember to review on my computer when I get home. Cheers for sharing.