Files
troupe-standup/wizard-work/null/base32c/README-base32c.md
T

73 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# base32c — Crockford Base32 with a check symbol (stdlib-only)
Lane: Codeforge (null). Built 2026-10-23.
Spec: https://www.crockford.com/base32.html (Douglas Crockford, 2019-03-04) — the
authoritative table was fetched during this build; the quoted rules live in the
`base32c.py` docstring (symbol set, I/L/O/U exclusions, i/l→1 and o→0 decode aliases,
zero-extension to a multiple of 5 bits, hyphens ignored on decode, check symbol =
value mod 37 over the 37-symbol alphabet `0-9 A-Z * ~ $ = U`).
## Files
base32c.py codec + argparse CLI (encode, decode, encode-checked, verify, roundtrip)
test_base32c.py 16-case evidence suite; exit 0 = all invariants hold, 1 = broken
mutation_check.py injects 6 faults into a scratch copy; exit 0 = every fault caught
crosscheck_oracle.py agreement run vs the independent PyPI package base32-crockford 0.3.0
demo_ids.py real-data demo: SHA-256 -> 128-bit hyphenated public ID + typo sweep
base32c-selftest.txt captured run of test_base32c.py
base32c-oracle.txt captured run of crosscheck_oracle.py
base32c-demo.txt captured run of demo_ids.py
## Reproduce (each command's own exit code is the verdict)
python3 test_base32c.py
python3 mutation_check.py
python3 demo_ids.py
/root/.hermes/profiles/null/cache/scratch/b32venv/bin/python3.14 crosscheck_oracle.py
## Measured results (this build, this machine)
test_base32c.py 16/16 cases pass, exit 0 [measured]
round trips 105,806 values (exhaustive 0..100,000 plus 2**k-1, 2**k, 2**k+1
for k=0..600 and 4,000 seeded randoms up to 1024 bits), each
checked by three independent decoders/encoders [measured]
mutation_check.py 6/6 injected faults killed, control copy passes, exit 0 [measured]
crosscheck_oracle.py 23,514 values agree with PyPI base32-crockford 0.3.0 on payload,
checked payload, check symbol, hyphenated decode and alias
handling; 18/18 junk rejections matched; 10/10 corrupted
check symbols rejected by both [measured]
single-symbol typos 9,808/9,808 rejected, of which 9,706/9,706 use a legal payload
symbol (the interesting case) [measured]
adjacent transpositions 27/27 rejected (all distinct-symbol adjacent swaps) [measured]
deletions 816/837 rejected (97.5%) [measured]
insertions 2,568/2,691 rejected (95.4%) [measured]
demo_ids.py GPL-3 sha256 -> id 1SEB-E9EH-7P96-FGZ6-SDQX-V6JV-SAE,
round-trip OK, 842/842 typos rejected, exit 0 [measured]
Why substitution and adjacent-transposition detection are 100% (not a coincidence):
substituting the symbol at weight 32**j by a different canonical digit changes the value
by d*32**j, 1 <= |d| <= 31; 37 is prime and 32**j is a unit, and |d| < 37, so the change is
never 0 mod 37. Adjacent swaps change the value by (a-b)*32**j*31 with a != b, |a-b| <= 31 —
also never 0 mod 37. The suite asserts both exhaustively rather than asserting the algebra.
## Limitations — stated, not hidden
* The check symbol is value-based, so edits that preserve the value are invisible:
deleting a leading `0`, or inserting `0` in front, still verifies. The suite asserts
this blind spot on purpose (`case_leading_zero_blind_spot_is_real`).
* Single deletions/insertions elsewhere are ~95–98% caught, not 100%; measured above.
* `min_length` pads with `0`, which is exactly what creates the leading-zero blind spot —
use it for display widths, not for extra integrity.
* Behavioural divergence from the PyPI oracle: its `decode(checksum=False)` treats a
trailing check-only symbol (`* ~ $ = U`) as a payload digit, so `a=` decodes to a number.
`base32c.decode` refuses check-only symbols in payload positions. In validating mode
(`decode_checked` / `oracle.decode(..., checksum=True)`) both reject. Not a bug on either
side — an ambiguity in the lax mode, recorded in `crosscheck_oracle.py`.
## Verdict
VERDICT: Crockford Base32 codec ships with 16/16 invariant cases, 6/6 mutants killed, and
23,514-value agreement with an independent PyPI implementation; the one real limitation
(leading-zero edits are invisible to a mod-37 check) is asserted in the suite, not hidden.