第 5 课
Base64 与 Hex 对比
何时选 Base64、何时选十六进制。
十六进制(Hex)把一个 半字节(nibble,4 bit) 展开成 0–9A–F 里的一个 ASCII 符号。Base64 则让每个输出字符承载 6 个比特——因而在“可见字符个数”意义上往往 比 Hex 更紧凑,尽管在 gzip 等大压缩语境下最终以字节计的体积优势还要另说。
膨胀比例(感性认识)
| 编码 | 每个输出符号承载的比特 | 字母表大小 |
|---|---|---|
| Hex | 4 | 16 |
| Base64 | 6 | 64 |
在不计额外边框的情况下,Hex 大约是 每个原始字节占用 2 个十六进制字符;Base64 大致约为 每 3 字节 → 4 字符(再考虑填充尾巴)。直觉上:同样一段原始二进制,Hex 往往更长,Base64 则更省字符数但有填充与字母表取舍。
举一个便于感受的例子:原始 16 字节,Hex 一般要 32 个字符,而 Base64 大概是 22 左右(对齐与填充会带来轻微出入)。
什么时候 Hex 更合适
在这些场景优先考虑 Hex:
- 需要人用肉眼对比 哈希指纹(下载页校验和、Git 对象摘要等)
- 希望规则极其直白:相邻两个 Hex 字符 = 一个字节,心智负担低
- 写一次性脚本调试,Base64的填充、
+//让人分心 - 某些比较/规范化流程要求统一的 大小写策略(全大写或全小写的 Hex)
很多工具链默认 Hex 并不是因为 Hex “更安全”,而是因为 可读与约定俗成。
什么时候 Base64 更合适
在这些场景优先考虑 Base64:
- 需要把二进制快速塞进 MIME、JSON-ish 信封、或与文本流水线兼容的载荷
- 希望相对 Hex 少打一些分隔用的可见字符,日志里整块更短一点(见仁见智)
- 生态已经规定用 Base64 包装(JWT、PEM 内的 DER …)
- URL 上下文若使用 URL-safe 变体,通常比一长串 Hex 更容易嵌进受限字符集(但仍要选对规范)
要记住:二者都 不压缩熵,选择属于 传输与集成体验,不属于“更强的编码”。
混在一起的管道里别串层
典型事故:界面展示 SHA-256 的 Hex 字符串,开发者却对 那段 Hex 文本的 ASCII 再做 Base64,而不是对 原始的 32 字节摘要 编码——结果就是“怎么都对不上校验和”。
要分清三层对象:
digest_bytes = 算法输出的原始字节(不透明)
hex_string = 给人看的字节视图(一串 '0–9a-f')
base64_view = 同一 digest_bytes 的另一种文本视图(不同字母表)
在各层之间转换时,要回到 完全一致的字节 再继续,而不是对“上一轮文本视图”想当然地层层套娃。
除非你遵循明确协议,“先 Hex 再 Base64” 这类组合拳通常 没有意义,只会加深误解。
性能不必过度纠结
在常见体量(至多几 MB)上,两类编码的计算成本都可忽略。互操作与可读性 / 规范性远比微基准重要。
要点小结
Hex:2 字符/字节,极其规整;Base64:更可打印环境下的密度折中。按协议编码 设计者意图的那串字节,并在文档写清楚校验端期望的是 digest 字节还是某种 已定稿的字符串规范化形式——这会省下大量无效的“灵异不一致”。