Skip to content
Also from us: TypologyOnline.com · Free personality tests

Ascii85 and Base85: Packing Binary Into Fewer Characters Than Base64

How 4 bytes become 5 printable characters, why Ascii85 is not encryption, and why Base85 still matters in files, programming tools, and binary-to-text encoding.

Try the Ascii85 / Base85 Encoder / Decoder tool
Illustration of bytes being packed into Ascii85 and Base85 printable characters
Ascii85 and Base85 treat bytes as numbers, then rewrite those numbers with compact printable alphabets.

Ascii85 and Base85 are binary-to-text encodings. They take raw bytes - the kind of data found inside files, images, compressed archives, executable data, or UTF-8 text - and rewrite those bytes using printable characters.

They are not ciphers in the modern security sense. They do not use a secret key. They do not encrypt a message. Anyone who recognises the format can decode it.

Their purpose is different: to make binary data survive in places that expect text.

Base64 is the better-known member of this family. It appears in email, data URLs, web APIs, certificates, tokens, and countless programming tasks. Ascii85 and Base85 solve a similar problem, but they do it more compactly. Base64 usually turns every 3 bytes into 4 characters. Ascii85 and Base85 turn every 4 bytes into 5 characters. That gives them about 25% overhead for full blocks, compared with Base64's roughly 33.3% overhead.

The catch is that "Base85" is not one single universal format. Ascii85, Adobe-style Ascii85, btoa-style Ascii85, Git-style Base85, RFC 1924 Base85, and Z85 are related ideas, but they differ in alphabets, wrappers, padding behaviour, and shorthand rules. That is why a good Ascii85 / Base85 encoder and decoder should let you choose the variant rather than pretending they are all identical.

Ascii85 / Base85 at a Glance

Feature Ascii85 / Base85
Type Binary-to-text encoding
Main purpose Represent bytes using printable text characters
Core mechanism 4 bytes become a 32-bit number, then become 5 base-85 digits
Common Ascii85 alphabet ASCII characters ! through u
Common non-Ascii85 alphabet RFC 1924-style / Git-style Base85 alphabet
Key None
Encryption? No
Decoding term Decode, not decrypt
Full-block expansion 4 bytes to 5 characters, about 25% overhead
Base64 comparison Base64 uses 3 bytes to 4 characters, about 33.3% overhead
Common Ascii85 wrapper <~ at the start and ~> at the end in Adobe-style examples
Useful shorthand z can represent four zero bytes in many Ascii85 variants
Security level No secrecy; encoding only

Ascii85 and Base85 are worth learning because they sit at a useful middle point. They are more mathematical than URL encoding, hex, or A1Z26, but still much easier to inspect than compression, encryption, or binary file formats.

They also teach a practical programming lesson:

Text is not the same thing as bytes.

A string like:

Hello

may look simple, but in a computer it is represented as bytes. In UTF-8, ordinary English letters usually use one byte each:

Character Byte value Hex
H 72 48
e 101 65
l 108 6c
l 108 6c
o 111 6f

Ascii85 does not really encode "letters". It encodes the underlying bytes.

Binary Data in a Text-Shaped World

Many systems were built around text. Early email systems, terminal tools, printers, source files, markup documents, and network protocols often expected data to be represented as printable characters. Arbitrary binary data can contain byte values that do not display cleanly, may be treated as control characters, or may be damaged by systems that wrap lines, strip spaces, or interpret special symbols.

Binary-to-text encoding solves this by turning arbitrary bytes into a restricted set of characters that can be copied, pasted, transmitted, embedded, or stored more safely.

Encoding Main idea
Hex / Base16 Each byte becomes two hexadecimal digits
Base32 Bytes become characters from a 32-symbol alphabet
Base64 3 bytes become 4 printable characters
Ascii85 / Base85 4 bytes become 5 printable characters
URL encoding Unsafe URL characters become % followed by hex bytes

Ascii85 and Base85 are more compact than hex and usually more compact than Base64, but they use a larger and sometimes more awkward character set. Hex is long but simple. Base64 is slightly longer than Base85 but widely standardised. Base85 is compact, but variant compatibility matters.

Four Bytes Become One Big Number

The central idea of Base85 is beautifully simple:

  1. Take 4 bytes.
  2. Treat them as one 32-bit integer.
  3. Convert that integer into 5 digits in base 85.
  4. Turn those 5 digits into printable characters.

Why 4 bytes?

Because 4 bytes contain 32 bits:

4 x 8 = 32

So 4 bytes can represent:

2^32 = 4,294,967,296

different values.

Now ask: how many different values can 5 base-85 digits represent?

85^5 = 4,437,053,125

That is just enough. Five base-85 digits can cover every possible 32-bit block because:

85^5 > 2^32

This is the neat mathematical reason Base85 works. Base64 uses 6-bit groups because 2^6 = 64. Base85 cannot be sliced as cleanly into bits, because 85 is not a power of 2. Instead of splitting the data into equal bit-sized chunks, Base85 treats each 4-byte block as a whole number and performs base conversion.

Encoding ABCD by Hand

Let us encode:

ABCD

In ordinary ASCII / UTF-8, those characters have these byte values:

Character Decimal byte Hex byte
A 65 41
B 66 42
C 67 43
D 68 44

Together, those four bytes form this 32-bit value:

65 x 256^3 + 66 x 256^2 + 67 x 256 + 68

That gives:

1,094,861,636

Now convert that number into five base-85 digits:

20, 82, 67, 80, 11

Ascii85 turns each digit into a printable character by adding 33, because the printable Ascii85 alphabet begins at ASCII code 33, the exclamation mark !.

Base-85 digit Add 33 ASCII code Character
20 53 53 5
82 115 115 s
67 100 100 d
80 113 113 q
11 44 44 ,

So:

ABCD

encodes as:

5sdq,

If Adobe-style markers are used, it may be written as:

<~5sdq,~>

Those wrapper symbols are not part of the data itself. They mark the start and end of the Ascii85 string in Adobe-style notation.

Why the Ascii85 Alphabet Runs from ! to u

The common Ascii85 alphabet uses 85 consecutive printable ASCII characters:

! " # $ % & ' ( ) * + , - . / 0 1 2 ... s t u

In codepoint terms, that is ASCII 33 through ASCII 117.

The advantage of this alphabet is mechanical simplicity. To encode a base-85 digit, add 33. To decode an Ascii85 character, subtract 33.

The disadvantage is that some of these characters have special meanings in programming languages, markup, shells, URLs, JSON strings, HTML, XML, and other text formats. Characters such as ", ', <, >, &, \, and / can be awkward depending on where the encoded text is placed.

That is one reason different Base85 variants exist. They are often trying to balance compactness against character safety.

Partial Blocks: What Happens to Hello?

Base85 works naturally on groups of 4 bytes. But real input does not always divide evenly into groups of 4.

Take:

Hello

That is 5 bytes in UTF-8. The first four bytes form a complete block:

H e l l

Ascii85 encodes that block as:

87cUR

The final byte is:

o

A one-byte leftover cannot form a full 32-bit block by itself. The usual Ascii85 method is:

  1. Pad the final block with zero bytes until it is 4 bytes long.
  2. Encode the padded 4-byte block into 5 Ascii85 characters.
  3. Keep only enough encoded characters to represent the original leftover data.
Leftover bytes Encoded characters kept
1 byte 2 characters
2 bytes 3 characters
3 bytes 4 characters
4 bytes 5 characters

So Hello becomes:

87cURDZ

With Adobe-style markers:

<~87cURDZ~>

Reading the Five Characters Backward

Decoding reverses the process.

Suppose we receive:

5sdq,

Ascii85 decoding subtracts 33 from each character's ASCII code:

Character ASCII code Minus 33 Base-85 digit
5 53 20 20
s 115 82 82
d 100 67 67
q 113 80 80
, 44 11 11

Now rebuild the number:

20 x 85^4 + 82 x 85^3 + 67 x 85^2 + 80 x 85 + 11

That gives:

1,094,861,636

Then split that number back into four bytes:

Byte Decimal Character
First 65 A
Second 66 B
Third 67 C
Fourth 68 D

So:

5sdq,

decodes to:

ABCD

This is why Base85 is not encryption. Nothing secret has happened. The data has merely been rewritten in a different base.

The z Shortcut for Four Zero Bytes

Ascii85 has a famous shorthand:

z

In many Ascii85 variants, the single character z means:

00 00 00 00

or four zero bytes.

Without the shorthand, four zero bytes would encode as:

!!!!!

The shorthand compresses this common block to:

z

However, z has a rule: it must represent a complete 4-byte zero block. It cannot appear halfway through a group. A strict decoder should reject misplaced z rather than guessing.

The Older y Shortcut for Four Spaces

Some btoa-style Ascii85 variants also support another shorthand:

y

This represents four space characters:

20 20 20 20

in hexadecimal.

That is useful in old text-heavy contexts where runs of spaces might appear often. But it is not universally supported. The same detail makes Base85 slightly treacherous: two strings may both look like "Ascii85", but one decoder may accept y while another rejects it.

A careful tool should make this option explicit.

Adobe Markers: <~ and ~>

Many Ascii85 examples are wrapped like this:

<~87cURDZ~>

The opening marker is:

<~

The closing marker is:

~>

These are commonly associated with Adobe-style Ascii85 notation. They are useful because they clearly show where the encoded text begins and ends.

The markers are not part of the original data. They are framing punctuation. Some contexts expect markers, some make them optional, and some forbid them.

Base85 Is a Family, Not One Format

The name "Base85" can cause confusion because it is used in both a general and a specific sense.

In the general sense, Base85 means:

Any encoding that uses 85 printable symbols to represent binary data compactly.

In the specific sense, a library may use "Base85" to mean a particular alphabet and padding convention.

Python's base64 module is a good illustration:

Python function Meaning
a85encode() / a85decode() Ascii85
b85encode() / b85decode() Git-style Base85
z85encode() / z85decode() Z85, associated with ZeroMQ

So if one Base85 decoder rejects another tool's output, the likely problem is not that the data is "wrong". It may simply be the wrong Base85 variant.

The RFC 1924 Alphabet

A particularly important Base85 alphabet appears in RFC 1924, A Compact Representation of IPv6 Addresses, published on 1 April 1996 by Robert Elz of the University of Melbourne. The RFC describes a way to represent a 128-bit IPv6 address in 20 base-85 characters and explicitly states that it is informational, not an Internet standard.

The RFC 1924 alphabet is:

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~

It deliberately omits certain awkward characters, including quotes, comma, period, slash, colon, square brackets, and backslash. Git-style Base85 and Python's b85encode() are associated with this style of alphabet.

Mode Alphabet style Wrappers z shorthand
Ascii85 ASCII ! through u Optional <~ ~> Commonly supported
Base85 / Git-style RFC 1924-style alphabet No Adobe wrappers Usually not used
Z85 ZeroMQ-style alphabet No Adobe wrappers Not used in the same way

The shared idea is always the same: encode 4 bytes as 5 printable characters. The differences are in the alphabet and surrounding rules.

Ascii85, Base85, and Base64 Compared

Base64 is more widely recognised than Ascii85. It is also more standardised for internet use. But Base85 is denser.

Encoding Input block Output block Approx. overhead
Hex / Base16 1 byte 2 chars 100%
Base64 3 bytes 4 chars 33.3%
Ascii85 / Base85 4 bytes 5 chars 25%

Take the phrase:

Hello, world!

Ascii85 with Adobe markers:

<~87cURD_*#TDfTZ)+T~>

Ascii85 without markers:

87cURD_*#TDfTZ)+T

Base85 using the RFC 1924 / Git-style alphabet:

NM&qnZ!92pZ*pv8Ap

Base64:

SGVsbG8sIHdvcmxkIQ==

Across larger binary data, Base85's 4-to-5 packing is usually more compact than Base64's 3-to-4 packing. The trade-off is that Base85 uses more punctuation, which can make it less convenient in URLs, HTML, JSON, shell commands, source strings, and configuration files.

Base64 is often more boring. That is one reason it is so useful.

Recognising Ascii85 and Base85 Text

Ascii85 and Base85 output often looks like dense punctuation-heavy text:

87cURD_*#TDfTZ)+T

or:

NM&qnZ!92pZ*pv8Ap

Some clues suggest Ascii85:

Clue Meaning
Starts with <~ and ends with ~> Likely Adobe-style Ascii85
Contains many punctuation characters Possible Base85 / Ascii85
Contains z as a standalone-looking character Could be Ascii85 zero-block shorthand
Uses characters in the range ! to u Consistent with Ascii85
Length is near 5/4 of binary size Consistent with Base85-style packing

Recognition is not always certain from appearance alone. Encoded text can be short, wrapped, embedded, escaped, truncated, or mixed with surrounding syntax.

The safest method is to try the correct decoder and check whether the result makes sense as bytes or UTF-8 text.

Decoding Errors and Format Clues

A good Ascii85 / Base85 decoder should complain clearly when the input is not valid.

Problem Example
Wrong alphabet Trying to decode RFC 1924 Base85 as Ascii85
Broken Adobe wrapper Starts with <~ but does not end with ~>
Invalid character A character outside the variant's alphabet
Misplaced z z appears inside a partial group
Unsupported y shorthand Input uses y, but the decoder does not allow it
Single leftover character One final Base85 digit cannot represent a byte in a strict decoder
Bad 5-character group The decoded number is larger than a 32-bit block

The single leftover character rule is worth highlighting. In Base85, a complete group has 5 characters and decodes to 4 bytes. A final group of 2, 3, or 4 characters can represent 1, 2, or 3 leftover bytes. But a final group of only 1 character does not carry enough information to recover even one original byte.

Base85 Is Not Encryption

Because online tools sometimes use labels like "Base85 decrypt" or "Ascii85 decrypt", it is worth being precise.

Ascii85 does not encrypt. Base85 does not encrypt. They encode.

Process Uses a secret key? Hides meaning from someone who knows the method? Example
Encoding No No Base64, Base85, hex, URL encoding
Encryption Yes Yes, if properly designed and keyed AES-GCM, ChaCha20-Poly1305
Hashing No, but one-way Not reversible SHA-256
Compression No Not intended for secrecy ZIP, gzip

If you encode:

SECRET MESSAGE

into Ascii85, anyone can decode it. You have not protected the message. You have only changed its representation.

Do not use Base85 to protect passwords, API keys, personal messages, private documents, recovery phrases, financial data, or authentication tokens.

A Full Encode/Decode Example

Let us encode:

Hello, world!

Using Adobe-style Ascii85, the output is:

<~87cURD_*#TDfTZ)+T~>

Without the Adobe markers, the body is:

87cURD_*#TDfTZ)+T

Now decode it. The decoder removes the wrapper, reads the Base85 characters in groups, turns each group back into bytes, and interprets the recovered bytes as UTF-8 text:

Hello, world!

Now encode the same phrase with RFC 1924 / Git-style Base85:

NM&qnZ!92pZ*pv8Ap

This is not the same output, even though the input is the same. That does not mean one is more correct. It means the alphabet and variant are different.

Python: Using the Built-In Ascii85 and Base85 Functions

Python already includes Ascii85 and Base85 support in its standard base64 module. That is the best starting point for real code.

import base64


message = "Hello, world!"
data = message.encode("utf-8")

ascii85 = base64.a85encode(data, adobe=True)
base85 = base64.b85encode(data)

print("Original text:", message)
print("Ascii85:", ascii85.decode("ascii"))
print("Base85 :", base85.decode("ascii"))

decoded_ascii85 = base64.a85decode(ascii85, adobe=True)
decoded_base85 = base64.b85decode(base85)

print("Decoded Ascii85:", decoded_ascii85.decode("utf-8"))
print("Decoded Base85 :", decoded_base85.decode("utf-8"))

Expected output:

Original text: Hello, world!
Ascii85: <~87cURD_*#TDfTZ)+T~>
Base85 : NM&qnZ!92pZ*pv8Ap
Decoded Ascii85: Hello, world!
Decoded Base85 : Hello, world!

This example shows the most important practical point:

Ascii85 and Base85 can encode the same data but produce different text.

The bytes are the same. The variant is different.

A Small Manual Ascii85 Encoder in Python

The built-in Python functions are best for real use, but a short manual encoder helps show how the mechanism works.

Python exampleShow code
def ascii85_encode(data):
    alphabet = ''.join(chr(i) for i in range(33, 118))
    output = []

    for i in range(0, len(data), 4):
        block = data[i:i + 4]
        original_length = len(block)

        if original_length < 4:
            block = block + b'\0' * (4 - original_length)

        value = int.from_bytes(block, byteorder="big")

        if value == 0 and original_length == 4:
            output.append("z")
            continue

        digits = []

        for _ in range(5):
            digits.append(value % 85)
            value //= 85

        digits.reverse()

        encoded = ''.join(alphabet[digit] for digit in digits)

        if original_length < 4:
            encoded = encoded[:original_length + 1]

        output.append(encoded)

    return ''.join(output)


text = "ABCD"
encoded = ascii85_encode(text.encode("utf-8"))

print(encoded)

Expected output:

5sdq,

This is deliberately simple. It shows the mechanism rather than trying to be a full replacement for Python's standard library.

Puzzles, ARGs, CTFs, and Programming Challenges

Ascii85 and Base85 are not as visually famous as Morse code, binary, Caesar cipher, pigpen, or A1Z26. They are less likely to appear in casual puzzle books because the output looks dense and unfriendly.

But they do appear in technical puzzle environments:

  • capture-the-flag challenges
  • programming puzzles
  • file-format exercises
  • ARG clue chains
  • escape-room style digital puzzles
  • geocaching mystery caches
  • "decode this string" challenges
  • steganography or binary-analysis tasks

In those settings, Ascii85 is often one step in a longer chain:

Base85 -> gzip -> plaintext

or:

Ascii85 -> hex -> XOR -> message

For puzzle solving, the important habit is not memorising every alphabet. It is learning to recognise layers of representation.

Ascii85 is one of those layers.

Common Questions About Ascii85 and Base85

Is Ascii85 the same as Base85?

Not exactly. Ascii85 is a type of Base85. It usually refers to the Adobe/btoa-style alphabet using ASCII characters ! through u.

Base85 is the broader family name. It may refer to Ascii85, RFC 1924-style Base85, Git-style Base85, Z85, or another related variant.

Is Base85 better than Base64?

It depends what "better" means.

Base85 is more compact for full blocks: 4 bytes become 5 characters. Base64 uses 3 bytes to 4 characters.

But Base64 is more widely standardised and often safer in common text contexts. Base85 uses more punctuation, which can be inconvenient in markup, strings, URLs, shells, and configuration files.

Why does Ascii85 sometimes start with <~?

That is an Adobe-style wrapper. It marks the beginning of an Ascii85 string with <~ and the end with ~>.

The wrapper is not part of the underlying byte data. It is framing.

What does z mean in Ascii85?

z is shorthand for four zero bytes:

00 00 00 00

It is a compression shortcut for a complete all-zero 4-byte block. It should not appear in the middle of a group.

What does y mean in Ascii85?

In btoa-style Ascii85, y can mean four spaces:

20 20 20 20

But it is not part of every Ascii85 form. Many decoders reject it unless explicitly configured to allow it.

Can Ascii85 encode Unicode text?

Yes, but it encodes the bytes, not abstract characters.

For example, the character é may be represented by more than one byte in UTF-8. Ascii85 encodes those UTF-8 bytes. When decoding, the bytes must then be interpreted using the correct character encoding.

For modern web tools, UTF-8 is the sensible default.

The Real Lesson of Ascii85 and Base85

Ascii85 and Base85 are not glamorous cryptography. They do not protect secrets. They do not resist attackers. They do not belong in the same security category as AES, ChaCha20-Poly1305, RSA, elliptic-curve cryptography, or modern authenticated encryption.

But they teach something essential.

They show how computers move between:

  • bytes
  • numbers
  • alphabets
  • printable text
  • file formats
  • transport-safe representations

They also reveal a practical truth about computing: many "mysterious strings" are not mysterious at all. They are ordinary bytes wearing a text costume.

Base85 is a particularly efficient costume. It packs 4 bytes into 5 characters. It uses a large alphabet. It has variants, shortcuts, wrappers, and compatibility traps. It is compact enough to be useful and structured enough to be educational.

If Base64 is the everyday workhorse of binary-to-text encoding, Ascii85 is its denser, sharper-edged cousin.

Useful, clever, but slightly less forgiving.

Continue with the Ascii85 / Base85 Encoder / Decoder Tool

Use the matching Ascii85 / Base85 Encoder / Decoder tool to experiment with your own examples.

Try:

Hello, world!

Then compare the output in:

  • Ascii85 with Adobe markers
  • Ascii85 without markers
  • Base85 / RFC 1924-style alphabet
  • decoded UTF-8 text
  • decoded hex bytes

Then try byte-oriented examples such as:

00 00 00 00

or:

41 42 43 44

The first shows the z shorthand in Ascii85. The second shows why ABCD becomes:

5sdq,

Once you understand that one example, the whole method becomes much less mysterious: Ascii85 is just binary data treated as numbers, then rewritten in a compact printable alphabet.

Sources and further reading

Try the Ascii85 / Base85 Encoder / Decoder Tool

Want to experiment with the idea in practice? Open the matching tool and try your own text.

Open Ascii85 / Base85 Encoder / Decoder
Signal acquired

A note from the team

We build these tools because we love cryptography, encoding, and making difficult ideas easier to explore. If they've helped you, even a small coffee means the world to the project. Thank you!

Say thanks on Ko-fi

Read next

Binary-to-Text Encoding Base64: The Encoding That Smuggles Binary Through Text How a simple 6-bit alphabet became one of the quiet workhorses of email, the web, APIs, certificates, tokens, and modern software plumbing. Binary-to-Text Encoding Base32: The Encoding That Makes Binary Easier to Read, Copy, and Survive How a 5-bit alphabet became a quiet helper in authenticator apps, DNS-safe strings, recovery codes, identifiers, and text-shaped software systems. Web Encoding URL Encoding: How the Web Makes Text Safe for Links Why spaces become %20, why & turns into %26, and how percent encoding lets ordinary text survive inside web addresses without breaking URL structure.
Back to all articles