What basE91 does
basE91 (sometimes written Base91) encodes arbitrary bytes into a string of printable ASCII characters so binary data can travel safely through text-only channels. Its appeal over Base64 is efficiency: it carries more information per output character, so encoded payloads are noticeably shorter.
How it works
The encoder treats the input as a stream of bits and reads them into a bit buffer. Whenever the buffer holds enough bits it pulls a value of either 13 or 14 bits — choosing 14 bits when the low 13 bits would exceed 88, which keeps every value below 8281 (that is 91 * 91). Each value is then written as two characters: the low digit is value mod 91 and the high digit is value / 91, both indexed into the 91-character alphabet.
v = buffer & 0x1FFF // try 13 bits
if v > 88: shift out 13 bits
else: v = buffer & 0x3FFF, shift out 14 bits
emit alphabet[v % 91], alphabet[v / 91]
Decoding reverses this: characters are read in pairs, recombined as low + high * 91, and the bits are streamed back out as bytes.
Why the 13/14 bit trick gives better density
The clever part of basE91 is the adaptive bit-width. If it always used 13 bits per two-character pair, each pair would carry log₂(91²) ≈ 13.15 bits of entropy, slightly better than Base64’s 6 bits per character. But by sometimes consuming 14 bits when the 13-bit value is small enough (≤88), the encoder extracts a bit more data from each character pair without exceeding the 91² symbol space. The result is an average payload density of roughly 13.3 bits per two output characters — about 16% better overhead than Base64.
In practical terms: a 100-byte binary encoded with Base64 produces about 136 characters. With basE91 the same 100 bytes typically produces around 123 characters — roughly 10% shorter.
The alphabet and its exclusions
basE91 uses 91 printable ASCII characters. The characters excluded from the 95 printable ASCII set are the 4 most likely to cause problems in text contexts:
- Single quote
'— breaks SQL and YAML string delimiters - Double quote
"— breaks JSON and HTML attribute values - Backslash
\— escape character in virtually all string literals - The soft-hyphen / certain extended characters
The remaining 91 printable characters are safe in most text environments without additional escaping, making basE91 practical for embedding in JSON values, source code comments, and configuration files.
When to use basE91 vs Base64
- Use basE91 when payload size matters (email attachments with strict size limits, embedded blobs in constrained bandwidth contexts) and you control both the encoder and decoder.
- Use Base64 when you need universal compatibility. Base64 is supported natively in every major language’s standard library; basE91 is not.
- Use basE91url (if you need URL safety) — there is no standard URL-safe basE91 variant, so for URLs stay with Base64url.
Remember that decoding yields raw bytes; this tool then interprets them as UTF-8, so feeding it a non-text binary will produce a decode error rather than readable text.