himitsu
Memorable secret generator with configurable word lists and templates.
Install
# Requires GNU coreutils (macOS: brew install coreutils)
git clone <repo> && cd himitsu
./install.sh
Usage
Generating secrets
himi # generate → clipboard
himi -o # generate → clipboard + stdout
himi -o secure # use 'secure' template → clipboard + stdout
himi -n 5 -o easy # generate 5 'easy' secrets → clipboard + stdout
himi -q # stdout only, skip clipboard (or HIMI_NO_CLIP=1)
himi test '{word}-{num:2}' # test a custom template
Use in scripts
# SSH key with generated passphrase (on clipboard too, ready to save)
ssh-keygen -t ed25519 -f mykey -P "$(himi -o)"
# Encrypt a file
openssl enc -aes-256-cbc -pbkdf2 -in secrets.tar -out secrets.enc -k "$(himi -o secure)"
# Generate and reuse in the same session
PASS="$(himi -o)"
htpasswd -b -c .htpasswd admin "$PASS"
# Wi-Fi password for a new AP
nmcli dev wifi hotspot ssid mynet password "$(himi -o wifi)"
Managing word lists and config
himi list # show lists and enabled status
himi add pokemon.txt # add + enable a list
himi disable pokemon # disable a list
himi enable pokemon # re-enable
himi rebuild # regenerate pool after manual changes
himi config # open config in $EDITOR (auto-rebuilds on change)
Checking entropy
himi entropy # show all templates with entropy
himi entropy secure # show specific template
TEMPLATE EXAMPLE ENTROPY
-------- ------- -------
default MAPLE42-river17-K7M93 ≈57.9 bits
easy crane-B4R-842 ≈38.8 bits
secure helm-river-A3K9P-fox-M2X8R! ≈94.4 bits
pin 483927 ≈19.9 bits
diceware crane-helm-tiger-river-maple ≈69.0 bits
wifi TIGER-maple4827 ≈42.9 bits
phone ACFG-KM3Y-XTWD ≈55.0 bits
Templates
Edit ~/.config/himi/config.sh to customize:
TEMPLATES=(
"default|{word!}{num:2}-{word!}{num:2}-{alpha:3}{num:2}"
"easy|{word}-{alpha:3}-{num:3}"
"secure|{word}-{word}-{alpha:5}-{word}-{alpha:5}{special:1}"
"pin|{num:6}"
"diceware|{word}-{word}-{word}-{word}-{word}"
"wifi|{word!}-{word!}{num:4}"
"phone|{safe:4}-{safe:4}-{safe:4}"
)
Tokens:
| Token | Output | Entropy |
|---|---|---|
{word} |
maple |
~13.8 bits* |
{WORD} |
MAPLE |
~13.8 bits* |
{Word} |
Maple |
~13.8 bits* |
{word!} |
maple or MAPLE |
~14.8 bits* |
{Word!} |
maple/Maple/MAPLE |
~15.4 bits* |
{alpha:N} |
N chars, Crockford Base32 | ~5.0 bits/char |
{safe:N} |
N chars, ultra-safe (no ambiguous chars) | ~4.6 bits/char |
{num:N} |
N digits | ~3.3 bits/char |
{special:N} |
N from !?@#%~=+ |
~3.0 bits/char |
{NAME:N-M} |
N to M chars from charset NAME | log2(Σ size^L) |
{hex:N} |
3f9a |
4.0 bits/char |
{b58:N} |
Vk2x (Base58, no 0OIl) |
~5.9 bits/char |
{b64:N} |
hG_4 (URL-safe base64) |
6.0 bits/char |
{alnum:N} |
xR4x |
~6.0 bits/char |
{ascii:N} |
p/(! (all printable, no space) |
~6.5 bits/char |
* Word entropy depends on pool size. Values shown assume all built-in lists enabled (~14k words, ~13.8 bits/word).
Custom charsets
Add "name|characters" entries to CHARSETS in the config, then use {name:N} or {name:N-M} in any template:
CHARSETS=(
"hex|0123456789abcdef"
"b58|123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
)
Names must match [a-z][a-z0-9_]* and override any built-in of the same name (alpha, safe, num, special, hex, b58, b64, alnum, ascii). Avoid duplicate characters; himi warns if it sees them, since they skew the distribution and overstate entropy.
Range tokens pick the length weighted by size^L, so every possible output is equally likely. {num:1-2} covers 0-99 plus 0-9 (110 outcomes, ~6.8 bits), not a 50/50 coin flip on length, which would tank min-entropy.
Integrity checks
himi rebuild records a SHA-256 of the pool; generation refuses if pool.txt was modified outside of himi (accidental edits, sync corruption, casual tampering). himi also refuses to source a config file that isn't owned by you or is group/world-writable, since the config is executed shell. Neither check stops an attacker who can already write to your home directory (nothing can), but they catch everything short of that.
Entropy rules of thumb
| Bits | Strength | Use case |
|---|---|---|
| ~40 | Casual | Low-value accounts, rate-limited logins |
| ~50 | Reasonable | Personal accounts |
| ~60 | Strong | Important accounts, recommended minimum |
| ~80 | Very strong | High-value targets, offline cracking resistance |
| ~128 | Paranoid | Nation-state threat models |
Online attacks (rate-limited) need far less entropy than offline attacks (cracking leaked hashes). When in doubt, aim for 60+ bits.
Uninstall
himi uninstall
Included Wordlists
Word lists are curled from GitHub and cleaned up. Here's how each built-in list was made, you can use these as examples in case you want to add your own. The built-in wordlists provide 15175 total words, after deduplication.
bips.txt (2048 words)
curl 'https://raw.githubusercontent.com/bitcoin/bips/master/bip-0039/english.txt' | \
tr -d '" ,[]\t' | tr 'A-Z' 'a-z' |
sed '/^$/d' | sort -u > bips.txt
eff.txt (7776 words)
curl 'https://www.eff.org/files/2016/07/18/eff_large_wordlist.txt | cut -f2' | \
tr -d '" ,[]\t' | tr 'A-Z' 'a-z' \
| sed '/^$/d' | sort -u > eff.txt
female_names.txt (4775 words)
curl 'https://raw.githubusercontent.com/arineng/arincli/refs/heads/master/lib/female-first-names.txt' \
| tr -d '\" ,[]\t' | tr 'A-Z' 'a-z' \
| sed '/^$/d' | sort -u > ftemp
curl 'https://raw.githubusercontent.com/attackdebris/kerberos_enum_userlists/refs/heads/master/Female_First_Names_Top_500.txt' \
| tr -d '" ,[]\t' | tr 'A-Z' 'a-z' \
| sed '/^$/d' | sort -u >> ftemp
curl 'https://raw.githubusercontent.com/righteousgambit/quiet-riot/refs/heads/main/wordlists/femalenames-usa-top1000.txt' \
| tr -d '" ,[]\t' | tr 'A-Z' 'a-z' \
| sed '/^$/d' | sort -u >> ftemp
cat ftemp | sort -u > female_names.txt
male_names.txt (1403 words)
curl 'https://raw.githubusercontent.com/arineng/arincli/refs/heads/master/lib/male-first-names.txt' \
| tr -d '" ,[]\t' | tr 'A-Z' 'a-z' \
| sed '/^$/d' | sort -u > mtemp
curl 'https://raw.githubusercontent.com/attackdebris/kerberos_enum_userlists/refs/heads/master/Male_First_Names_Top_500.txt' \
| tr -d '" ,[]\t' | tr 'A-Z' 'a-z' \
| sed '/^$/d' | sort -u >> mtemp
curl 'https://raw.githubusercontent.com/righteousgambit/quiet-riot/refs/heads/main/wordlists/malenames-usa-top1000.txt' \
| tr -d '" ,[]\t' | tr 'A-Z' 'a-z' \
| sed '/^$/d' | sort -u >> mtemp
cat mtemp | sort -u > male_names.txt
pokemon.txt (1024 words)
curl 'https://raw.githubusercontent.com/sindresorhus/pokemon/main/data/en.json' \
| tr -d '" ,[]\t' | tr 'A-Z' 'a-z' \
| sed '/^$/d' | sort -u > pokemon.txt
greek_gods.txt (445 words)
curl 'https://raw.githubusercontent.com/katkaypettitt/greek-gods/refs/heads/main/greek_gods.csv' \
| cut -d ',' -f1 | tr -d ' [],\"' |tr 'A-Z' 'a-z' | sort -u > greek_gods.txt
colors.txt (5611 words)
curl -Ls 'https://raw.githubusercontent.com/meodai/color-names/refs/heads/main/src/colornames.csv' | \
awk -F',' 'NR > 1 {print $1}' | grep -E "^[A-Za-z]{4,12}$" | tr 'A-Z' 'a-z' \
>> colors.tmp
curl -Ls 'https://raw.githubusercontent.com/k-kawakami/colorfulnet/refs/heads/master/example_data/wikipedia-list-of-colors.txt' | \
tr 'A-Z ' 'a-z\n' | tr -d '()' | grep -E "^[a-z]{4,12}$" | sort -u >> colors.tmp
cat colors.tmp | sort -u | tee colors.txt | wc -l
food.txt (1307 words)
curl -Ls 'https://raw.githubusercontent.com/schollz/food-identicon/master/ingredients.txt' | \
grep -Ev "(\ |:|â|¼|ã|\.)" | tr 'A-Z' 'a-z' | \
grep -E "^[a-z-]{4,12}$" >> food.tmp
curl -Ls 'https://gist.githubusercontent.com/peterdemin/920ec3eaaa0a9f3cafd3a855557f5e0c/raw/9c7337d7f6274de704f9018ed363d51dd7a0b128/food.txt' | \
tr ' -' '\n' | tr 'A-Z' 'a-z' | \
grep -E "^[a-z]{4,12}$" | sort -u >> food.tmp
cat food.tmp | sort -u | tee food.txt | wc -l
animals.txt (1109 words)
curl -Ls 'https://raw.githubusercontent.com/skjorrface/animals.txt/refs/heads/master/animals.txt' | \
tr ' ' '\n' | tr 'A-Z' 'a-z' | grep -E "^[a-z-]{4,12}$" | \
sort -u >> animals.tmp
curl -Ls 'https://raw.githubusercontent.com/timgates42/animal-list-factory/refs/heads/master/animals.txt' | \
tr 'A-Z' 'a-z' | grep -E "^[a-z-]{4,12}$" | \
sort -u >> animals.tmp
curl -Ls 'https://raw.githubusercontent.com/juliandefreitas/entity_lists/refs/heads/master/animals.csv' | \
tr 'A-Z' 'a-z' | grep -E "^[a-z-]{4,12}$" | \
sort -u >> animals.tmp
curl -Ls 'https://raw.githubusercontent.com/MikeInnes/SourceWalk.jl/refs/heads/master/animals.txt' | \
tr 'A-Z' 'a-z' | grep -E "^[a-z-]{4,12}$" | \
sort -u >> animals.tmp
cat animals.tmp | sort -u | tee animals.txt | wc -l