From b86289a348a027b67239e5a5609d16d4535ad67d Mon Sep 17 00:00:00 2001 From: lark Date: Wed, 10 Jun 2026 00:58:23 -0700 Subject: [PATCH] functionality for charsets added --- .DS_Store | Bin 0 -> 6148 bytes README.md | 21 +++ config.sh | 22 ++- himi | 475 +++++++++++++++++++++++++++++++++++++++-------------- install.sh | 8 +- 5 files changed, 400 insertions(+), 126 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..814b35fd98e8efa1e32a2acdba6b6ce72536ea5d GIT binary patch literal 6148 zcmeHKOHRW;4E2*mUD%!*oG>cpcg=C_*9xO6>0am414w*fXlGp2t1EX)hM7y zEKpV1lIM9mb|!fvjbkEm^KCUFni5e4WgJZ~{2;u}+LMub&VVjGqp6x@C}Rx0SaTdE z1AKO;6lg^aZK!j87qq1(I9Jd>cT|z5dy23t%$~oG8YfQ!q2Xb+SjKw2N5Mcw9gCt2 zu|!68_4@Yt^6`E>yiXmgKV+>RdvCY*qGlQc#(*(!gbeV_4av?0Z8Qdq0b^jt0N)QD z%9ty*g6ZnOkXiuX815vnxtHJ^ub3;gf>?n#Nd-!((-y-?I{aSaa>Z6q(#dJ_;dE!G z9g0i4?lgkBdGzN@;E(0eropSxZ`Mv+|CfUpwFb0l_0XHrd#T=icwYB$gTx&h_ q7RthLt>7*NMk>XKM041596R!jZ> literal 0 HcmV?d00001 diff --git a/README.md b/README.md index 5f229b1..74b5a0b 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ 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 ``` @@ -93,9 +94,29 @@ TEMPLATES=( | `{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) | \* 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: + +```bash +CHARSETS=( + "hex|0123456789abcdef" + "b58|123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" +) +``` + +Names must match `[a-z][a-z0-9_]*` and override the built-in four (alpha, safe, num, special). 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 | diff --git a/config.sh b/config.sh index 893a744..f00247d 100644 --- a/config.sh +++ b/config.sh @@ -1,6 +1,10 @@ # secret config — source'd by the secret command # Location: ~/.config/himi/config.sh +# Schema version — himi nags if this is older than what it expects. +# After merging new options into an existing config, bump this to match. +CONFIG_VERSION=2 + # ------------------------------------------------------------------------------ # Character sets for random portions # ------------------------------------------------------------------------------ @@ -11,6 +15,17 @@ SAFE_CHARSET='ACDEFGHJKMNPQRTWXY234679' NUM_CHARSET='0123456789' SPECIAL_CHARSET='!?@#%~=+' +# ------------------------------------------------------------------------------ +# Custom charsets (optional) +# Format: "name|characters" — use as {name:N} or {name:N-M} in templates. +# Names: lowercase, matching [a-z][a-z0-9_]*. Entries here override the +# built-in four. Avoid duplicate characters (skews the distribution). +# ------------------------------------------------------------------------------ +CHARSETS=( +# "hex|0123456789abcdef" +# "b58|123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" +) + # ------------------------------------------------------------------------------ # Word filtering (applied when building pool.txt) # ------------------------------------------------------------------------------ @@ -27,10 +42,9 @@ WORD_MAX_LENGTH=9 # {Word} — random word (Title Case) # {word!} — random lower or UPPER (+1 bit entropy) # {Word!} — random lower/Title/UPPER (+1.58 bits entropy) -# {alpha:N} — N chars, Crockford Base32 (5.0 bits/char) -# {safe:N} — N chars, ultra-safe (4.6 bits/char) -# {num:N} — N digits (3.3 bits/char) -# {special:N} — N characters from SPECIAL_CHARSET +# {NAME:N} — N chars from charset NAME (alpha/safe/num/special/custom) +# {NAME:N-M} — N to M chars, weighted so every output is equally likely +# (entropy = log2 of total outcomes, e.g. {num:1-2} ≈ 6.8 bits) # ------------------------------------------------------------------------------ TEMPLATES=( "default|{word!}{num:2}-{word!}{num:2}-{alpha:3}{num:2}" diff --git a/himi b/himi index 362128b..0de2918 100644 --- a/himi +++ b/himi @@ -6,19 +6,28 @@ set -euo pipefail # # Usage: # himi rebuild Rebuild pool from enabled lists -# himi Generate secret (default template) → clipboard -# himi