LogoBase64 解码

Base 家族全景:Base16 / Base32 / Base58 / Base64 / Base85 对比

同一段二进制数据,用不同的 Base 编码写出来,长度可以差出一倍。选错编码有时只是多占点带宽,有时会让地址没法双击选中、验证码被用户看错,或者让 PDF 解析器直接报错。这里用同一段 15 字节的输入 Hello, Base64! 统一演示,把五种常见 Base 编码的输出摆在一起看。

一、同一件事的几种做法:把二进制变成可打印文本

Base 家族做的事只有一件:把不能直接放进文本通道的字节,映射成一组可打印字符。区别在于每组拿几个比特去换一个字符。Base16 每 4 比特换 1 个字符,Base32 每 5 比特换 1 个,Base64 每 6 比特换 1 个,Base85 把 4 字节(32 比特)整体换算成 5 个字符。每字符携带的比特越多,膨胀率越低,但字符集越大、实现越复杂、对通道的兼容要求也越高。

输入统一为 Hello, Base64!(15 字节),结果如下:

编码输出示例输出长度膨胀率
Base16 (Hex)48656c6c6f2c204261736536342130+100%
Base32JBSWY3DPFQQFO33SNRSCC===24(含填充)+60%
Base58AXE8YfTf2yW5mHh
(示意,随字母表变体略有差异)
≈21≈+40%
Base64SGVsbG8sIEJhc2U2NCE=20+33%
Base85 (Ascii85)87cURD_*#TDfTZ)+T19+25%

Base58 的精确输出取决于具体字母表(Bitcoin 版与 Flickr 版不同),它不是按位分组,而是按大整数除法运算,长度并不严格固定。Base85 的输出以 Python a85encode 为参考。

二、Base16(Hex):膨胀 100%,但调试最好读

Base16 就是十六进制。每个字节拆成两个 4-bit 半字节,分别映射到 0-9 和 A-F。15 字节的 Hello, Base64! 变成 30 个字符,长度翻倍。

它的膨胀率在家族里最高,换来的是零歧义:没有填充符,没有大小写变体带来的映射差异,任何文本编辑器、日志管道、人的眼睛都能直接读。哈希值展示、内存地址、颜色码、调试输出默认都用它,不是因为效率高,而是因为不需要额外解释。

在拿 Base64 结果做长度对比之前,可以先在 Base64 在线编码解码 里取一个基准值,再回到 Hex 看翻倍后的长度,直观感受可读性溢价有多大。反过来,把同一段 Hex 丢进 Hex 转 Base64,就能看到 30 个字符被压缩到 20 个的过程。

三、Base32:膨胀 60%,只在字符集受限时用

Base32 每 5 比特映射一个字符,字母表通常取 A-Z 加 2-7,刻意排除了 0/O 和 1/I/L 这类手写、口述时容易混淆的字符对。15 字节输入产出 24 个字符(含填充),膨胀 60%。

它比 Base64 长,之所以还要用,是因为通道限制比带宽更硬。TOTP 双因素验证码需要用户手动输入,字母表必须排除易混字符;DNS 子域名不区分大小写,Base32 天然无小写字母,不会因为大小写折叠导致解码歧义。Crockford Base32 进一步把字母表改为 0-9 加去除 I/L/O/U 的大写字母,专为人类转录设计。

Base32 为什么长:5 比特的映射粒度意味着每 5 个字节(40 比特)刚好编成 8 个字符,但输入不是 5 的倍数时就要补零加填充。相比 Base64 的 3 字节到 4 字符,Base32 的 5 字节到 8 字符在输入长度不规整时浪费更多。

四、Base58:Bitcoin 地址为什么去掉 0OIl/+

Base58 不是 2 的幂次编码。它直接拿掉 Base64 字母表里的 0(零)、O(大写 o)、I(大写 i)、l(小写 L),再去掉 + 和 /,剩下 58 个字符。

这六个字符被剔除的理由很具体:前四个在大多数字体下肉眼难辨,后两个会破坏双击选中整段字符串的体验(+ 和 / 在很多 UI 里不被视为单词字符)。Bitcoin 地址需要被用户从屏幕上抄写、从聊天记录里复制、在纸质钱包上印刷,字符歧义造成的资金损失不可接受。

代价是 Base58 的编解码走大整数除法,而不是 Base64 那种位移掩码,CPU 开销明显更高。它适合编码短而关键的标识符(地址、密钥指纹),不适合大批量二进制数据。

五、Base64:膨胀 33%,通用平衡点

Base64 每 3 字节(24 比特)切成 4 组 6 比特,映射到 A-Z、a-z、0-9、+、/。15 字节输入在补一个零字节后编成 20 个字符,膨胀 33%。

它是绝大多数场景的默认答案:MIME 邮件附件、Data URL 内嵌图片、JWT 的 payload 段、PEM 证书主体。原因不在效率最优(Base85 更优),而在生态覆盖最广:标准库到处都有,浏览器原生支持 btoa/atob,任何文本协议都认得它。

URL 场景下需要换用 Base64url 变体:+ 换成 -,/ 换成 _,填充 = 通常省略。这不是另一套编码,只是索引 62 和 63 换了个字符,避免在查询串和路径里被错误解析。

六、Base85 / Ascii85 / Z85:膨胀 25%,PDF 字体流与嵌入式设备为什么爱用

Base85 把 4 字节当作一个 32 位大整数,除以 85 取余,得到 5 个字符。膨胀率降到 25%,比 Base64 少浪费约 6 个百分点。

Ascii85 是 Adobe 为 PostScript 和 PDF 定义的变体,字母表取 ASCII 33 到 117(! 到 u),四个零字节可以缩写成单个 z,并用 <~ ~> 做帧定界。PDF 的字体流和嵌入图像用它,因为 PDF 解析器本来就按这个规则读。

Z85 是 ZeroMQ 的变体,字母表刻意排除了引号、反斜杠、逗号、分号等字符,使得编码结果可以直接粘进源代码字符串字面量里而不需要转义。代价是输入长度必须是 4 的倍数,且没有 z 零组缩写。

选 Base85 之前要先确认解码端认哪一套字母表。Ascii85、Z85、RFC 1924 的 Base85 三者输出互不兼容,用错变体解码会得到乱码或直接报错。同一份 JSON 配置,在 Base64 里是一个长串,在 Ascii85 里是另一个更短的串,换到 Z85 又变一次。用 JSON 转 Base64 可以拿来对照,但换到 Base85 时务必先对好变体名。

反过来核对时,Base64 转 Hex 能直接暴露两者在字节层面的等价性:Base64 和 Hex 不是竞争关系,只是同一堆字节的两种写法,互转是无损的。

七、一张选型表:字符集限制、膨胀率、可读性、是否 URL 安全

选型的第一原则不是哪个最短,而是传输通道允许什么字符。通道卡死的时候,膨胀率再好看也用不了。

编码膨胀率字符集约束人类可读性URL 安全典型场景
Base16+100%仅 0-9A-F,最宽松最高,零歧义安全哈希展示、调试、颜色码
Base32+60%大写字母+数字,排除易混高,适合手输安全(无小写)TOTP 密钥、DNS、人工转录
Base58≈+40%排除 0OIl/+,58 字符中,防混淆但计算慢安全Bitcoin 地址、短标识符
Base64+33%含 +/,标准表低,需填充需 Base64url邮件、Data URL、JWT、证书
Base85+25%因变体而异(Ascii85 含引号等)低,不可手输视变体PDF 流、ZeroMQ 密钥、源码内嵌

按传输约束优先排序:通道只认十六进制,用 Base16;通道不区分大小写或需人工输入,用 Base32;通道是 URL 且需最短,用 Base64url;通道允许宽字符集且追求最小体积,用 Base85(先确认变体);地址类短标识需防抄错,用 Base58。

延伸阅读:Hex 与 Base64 互转拆解两种最常用写法之间的字节级对应关系;三种安全文本选型从攻击面角度比较 Base64、Base58、Base85 在令牌和标识符场景下的取舍。