macula_z32 (macula v4.3.0)
View Sourcez-base-32 codec (Phil Zimmermann's "Human-Oriented Base-32 Encoding"). Alphabet: ybndrfg8ejkmcpqxot1uwisza345h769.
Used by Macula to encode 32-byte Ed25519 pubkeys as DNS-label- friendly strings: 32 bytes → 52 ASCII characters, comfortably within DNS's 63-char per-label cap. PKARR (the public-key-addressable resource record convention) and projects like Pubky use this same encoding for the same reason.
Encoding direction: bit stream is taken MSB-first from the input bytes, grouped into 5-bit chunks (the final chunk zero-padded on the right if the input length is not a multiple of 5 bits). Each chunk indexes into the alphabet.
Decoding is the inverse: characters → 5-bit values → bit stream → 8-bit byte stream, dropping any trailing bits left over from the encoder's right-padding.
Length convention (the cases that matter for Macula): - 32 bytes (Ed25519 pubkey) → 52 chars - 16 bytes (UUID-like) → 26 chars - empty → empty
Reference: Phil Zimmermann's z-base-32 spec.
Summary
Functions
Decode a z-base-32 string back into its original bytes. Returns {error, invalid_z32} on any character outside the alphabet, or when the input length is not a valid encoding of a whole-byte payload (i.e., the bit length isn't a multiple of 8 within the rounding-up tolerance).
Encode a binary into its z-base-32 representation.
Check whether a binary is a syntactically valid DNS label under the z-base-32 alphabet (every character is in the alphabet, length is between 1 and 63 octets, and it decodes cleanly to a whole-byte payload).
Functions
Decode a z-base-32 string back into its original bytes. Returns {error, invalid_z32} on any character outside the alphabet, or when the input length is not a valid encoding of a whole-byte payload (i.e., the bit length isn't a multiple of 8 within the rounding-up tolerance).
Encode a binary into its z-base-32 representation.
Check whether a binary is a syntactically valid DNS label under the z-base-32 alphabet (every character is in the alphabet, length is between 1 and 63 octets, and it decodes cleanly to a whole-byte payload).