Upload a file
  1. base64hub
  2. Other bases
  3. Base91

Base91 Encoder and Decoder (basE91)

Type text to get basE91, the encoding that packs binary data into 91 printable ASCII characters. For random data it is about 8% shorter than Base64, at the cost of a less friendly alphabet.

Free no sign-up, no limits Local nothing uploaded ~23% overhead on random data Updated Oct 27, 2026
Input 0Bytes 0 BOutput 0

Processed in your browser. This page cannot send your data anywhere – how we know

How to encode and decode Base91

  1. Type or paste text into Input · Text. The encoded string appears in Output · basE91.
  2. For binary data, set From to Hex or Base64 and paste it in that form.
  3. To decode, click basE91 → Text in the direction toggle. Line breaks in the input are ignored; any other character outside the alphabet stops decoding with its position.
  4. Copy output or Download the result. For decoded binary data use Save bytes.

How basE91 works

basE91 was published by Joachim Henke. Base64 maps every 6 bits to one character. basE91 instead collects input bits into a queue and takes 13 bits at a time. Two characters can represent 91 × 91 = 8281 values, a little more than the 8192 that 13 bits need. The spare room is used for an optimization: when the next 13 bits have a value of 88 or less, the encoder takes 14 bits instead, and still writes two characters.

That makes the output length depend on the content. For random data, 14-bit groups are rare (under 1.1% of groups), so the overhead is close to 16/13, about 23%. Data with many zero bits packs better: 1000 zero bytes encode to 1143 characters, 14% overhead.

InputbasE91Base64
testfPNKddGVzdA==
Hello>OwJh>ASGVsbG8=
Hello World!>OwJh>Io0Tv!8PESGVsbG8gV29ybGQh
4 zero bytesAAAAAAAAAAA==
1000 random bytesabout 1230 characters1336 characters

The variable groups have a side effect: there is no fixed block size, so you cannot decode from the middle of a string or split it at arbitrary points. Base64 can be split at any multiple of 4 characters.

The alphabet and where it causes trouble

The basE91 alphabet is A–Z, a–z, 0–9 and these 29 characters:

!#$%&()*+,./:;<=>?@[]^_`{|}~"

It leaves out space, ', - and \. Space and ' cause trouble in shells and quoted strings, and \ is an escape character almost everywhere. The double quote is still in, along with <, > and &, so basE91 inside JSON, HTML or XML needs escaping, and the escapes eat part of the gain over Base64. It works best in places that take any printable ASCII, such as a text file, a single-quoted shell argument or a binary-safe protocol field.

A basE91 encoder in Python

There is no basE91 in the standard library. Henke’s algorithm is short enough to include:

ALPHABET = ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
            "0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~\"")

def b91encode(data: bytes) -> str:
    out, queue, nbits = [], 0, 0
    for byte in data:
        queue |= byte << nbits
        nbits += 8
        if nbits > 13:
            value = queue & 8191
            if value > 88:
                queue >>= 13
                nbits -= 13
            else:
                value = queue & 16383
                queue >>= 14
                nbits -= 14
            out += ALPHABET[value % 91], ALPHABET[value // 91]
    if nbits:
        out.append(ALPHABET[queue % 91])
        if nbits > 7 or queue > 90:
            out.append(ALPHABET[queue // 91])
    return "".join(out)

b91encode(b"test")    # 'fPNKd'

It produces the same output as this page for any input. More on byte handling in Python is on the Python page.

When to choose Base91

Pick basE91 when every byte of output counts and the channel accepts nearly all printable ASCII: compact logs, or text fields with a hard length limit. For anything that goes into JSON, URLs, HTML or email, Base64 is safer and almost as short, and Ascii85 is standardized in PDF and PostScript if you want 25% overhead with fixed blocks.

FAQ

Which characters does Base91 use?

All 95 printable ASCII characters except space, apostrophe ', hyphen - and backslash \. That leaves letters, digits and 29 punctuation marks, including the double quote.

Is Base91 smaller than Base85?

Slightly. Random data grows by about 23% in basE91 and exactly 25% in Base85; 100,000 random bytes became 122,976 characters here against 125,000 in Ascii85. Data with long runs of zero bytes shrinks further, down to about 14% overhead.

Why is Base91 not more widely used?

It has no RFC, its output contains " and other characters that need escaping in JSON, shells and HTML, and its variable bit groups make it slower and harder to implement than Base64. The few percent saved rarely outweigh that.

Can I decode Base91 written by another library?

Only if it uses Henke’s basE91 alphabet and bit order, which most do. A few libraries ship their own Base91 alphabets; their output decodes here without an error but gives wrong bytes.