Base85 / Ascii85 编码完全指南:比 Base64 更省空间的二进制编码
Base85 把每 4 字节打包成 5 字符,膨胀只约 25%,比 Base64 的 33% 省一截。本文讲清 Ascii85 与 Z85 的区别、PDF 与 git 里的用途,还给出一个真实编码示例。
Base85 / Ascii85 编码完全指南:比 Base64 更省空间的二进制编码
要把二进制数据塞进只能放文本的地方,大多数人第一反应是 Base64。但 PDF 流、PostScript 文档和 git 的二进制补丁都没用 Base64,它们选了一个更省空间的方案:Base85,也就是 Adobe 那套常叫 Ascii85 的编码。这篇把它讲透,顺便和 Base64 摆在一起比一比。
Base85 到底省在哪
核心就一句话:Base85 把每 4 字节打包成 5 个可打印字符,Base64 是每 3 字节变 4 个字符。
算一下膨胀率就清楚了。Base64 的 4/3 ≈ 1.333,也就是体积涨 33%。Base85 的 5/4 = 1.25,体积只涨 25%。差出来的 8 个百分点不算小:同样一份 1 KB 的二进制数据,Base64 输出约 1366 个字符,Base85 只要约 1280 个。当每个字节都金贵,比如二维码容量、URL 片段预算、数据包头,这点差距就是实打实的余量。
为什么偏偏是 85?因为 85 的 5 次方等于 44.4 亿,刚好够装下一个 32 位整数的全部取值(42.9 亿)。84 的 5 次方就不够了,86 又浪费。85 是能把 4 字节正好编成 5 字符的最小底数,不多不少。
Ascii85 和 Z85:两套不一样的字母表
Base85 不止一种。最常见的是两套:
Adobe 的 Ascii85 用 !(ASCII 33)到 u(ASCII 117)这 85 个字符。它里面有反斜杠、引号这些字符,放进源码字符串里很碍事,得各种转义。
ZeroMQ 的 Z85 是后来专门为「能直接粘进代码」设计的,它避开了反斜杠、反引号和引号,所以编出来的串能干干净净地塞进双引号字符串、JSON 值或者 shell heredoc,一个转义都不用加。
它俩打包逻辑一样(4 字节到 5 字符),但字母表完全不同。所以一个最常见的坑是:把 Ascii85 的串当 Z85 去解,轻则遇到字母表外字符报错,重则解出一串错误字节还以为成功了。选变体一定要跟数据当初的编码方式对上。
一个真实的编码示例
光说不练没感觉,拿中文跑一遍。输入 你好,工具先用 UTF-8 把它转成 6 个字节,再做 Base85 运算。
输入: 你好
UTF-8: E4 BD A0 E5 A5 BD (6 字节)
Ascii85: k0eDjGl
Z85: v3+:[wb
解码时反过来:把字符还原成字节,再跑一遍 TextDecoder('utf-8'),你好 原样回来,一个字都不差。emoji 同理,🚀 是 4 字节的 UTF-8 序列,照样能往返。关键就在「先按 UTF-8 取字节再编码」这一步,很多简陋实现没做这件事,一遇到非 ASCII 字符就乱码,而正确的实现是个真正的 Unicode 编解码器。
你可以直接在 /zh/t/base85-encoder/ 上把上面的例子跑一遍,左边输文本右边出结果,Ascii85 和 Z85 随手切换。
它都用在哪些地方
Base85 不是个玩具编码,几个大场景天天在用它:
PDF 和 PostScript。Adobe 的流可以用 /ASCII85Decode 过滤器,数据被包在 <~ 和 ~> 之间。这对定界符让解析器一眼看出编码块从哪开始到哪结束。要从 PDF 里抠一段流出来分析,把整段(连标记带换行)粘进解码器就行,标记和空白都会自动处理掉。
git 的二进制补丁。git diff --binary 生成的二进制增量用的就是带长度前缀的 Base85。如果一个补丁打不上,怀疑某行在传输里被截断了,把可疑段落切到解码模式,工具会指出字母表在第几个字符断掉,直接定位到丢字节的那一行,省得在整个 hunk 里瞎猜。
源码内嵌。要在配置文件或脚本里夹一张小查找表、一把密钥,又不想单独带个二进制文件,Z85 就很合适,粘进字符串不用转义。
那还要 Base64 干嘛
说了这么多 Base85 的好,得讲清楚它的边界,不然就成了误导。
放进 URL 或邮件,Base64 仍然是更稳的默认。两种 Base85 字母表都含标点,在这些场景里会被 percent-encode 或者直接弄乱。要往 URL 里塞,该用 URL-safe Base64 或者专门的 /zh/t/base64-encoder/,Base85 留给二进制流和源码内嵌。
还有个细节别忘:输入不是 4 字节整数倍时,会多出一个不完整的尾组,别拿干净的 4 比 5 去硬套输出长度。
我自己第一次踩坑就是在 Z85 模式下去解一段带 <~ ~> 定界符的 Ascii85 块,尖括号落在 Z85 字母表外直接报错,愣是查了半天才反应过来是变体选错了。后来养成习惯:解码前先确认这串数据当初是按哪个变体编的,而不是看哪个能解出东西就用哪个,因为 Ascii85 的串有时按 Z85 也能解出看着像样的字节,得拿结果再编一遍能还原成原文才算数。
小结
Base85 用 4 字节到 5 字符的打包,把膨胀率从 Base64 的 33% 压到约 25%,这正是 PDF、PostScript 和 git 选它的理由。记住三点就够用:Ascii85 和 Z85 字母表不同别混用;往 URL 和邮件里还是用 Base64;选对变体比解出来不报错更重要。剩下的,丢进工具里跑一遍最直观。
Made by Toolora · Updated 2026-06-13