什么是 Base32 和 Base58?
它们是同一个问题的两种答案:一个只能承载文本的信道被要求承载字节。Base32 和 Base58 既不是加密也不是哈希 — 它们既不隐藏任何内容,也不缩短任何内容。它们用一组固定的可读字符改写一个字节串,任何知道用的是哪一组的人都能直接还原。偏好哪一个的唯一理由,是接收方拿这些字符去做什么。
两个家族以完全不同的方式完成这种改写,而这个差异几乎解释了本页所有的意外:
- 比特打包 — Base32、Base32 Hex、Crockford Base32、z-base-32。字节被切成固定分组,每五个比特变成一个字符。输出长度可由输入长度推知,最后未填满的分组要么用填充字符标记,要么保持短缺。
- 大数转换 — 所有 Base58 表。整个字节串被当作一个以 256 为底的巨大数字读入,再以 58 为底写出。没有分组也没有填充;长度不能被整除,每个前导零字节变成一个前导零符号。
数据比特的去向:Base32 每字符承载 5 个比特,所以每 5 个输入字节需要 8 个字符 — 约膨胀 60%。Base58 每字符约 5.86 个比特,膨胀约 37%。Base64 每字符 6 个比特,膨胀 33%。字母表越大越短、也越难读出声,这正是每种方案所做的取舍。
本页的七个字母表
每个字母表都完整印出而非口头描述,因为两个在同名之下打印不同字符的工具,无论标签怎么写都不会彼此一致。RFC 4648 行是规范性的;Crockford 与 z-base-32 行遵循格式作者发布的定义;三个 Base58 行是广泛流传的惯例而非标准,因此分开列出。
Crockford Base32 与模 37 校验符号
该字母表去掉了 I、L、O 和 U,使任何符号都不可能被读成另一个。剩下的部分输入时大小写不敏感:i 和 l 读作数字 1,o 读作数字 0,连字符只用于让长串更易读。在此基础上,格式还定义了可选的校验符号:把符号串当作 32 进制数求值,对 37 取模,值 32 到 36 用五个额外符号书写。
校验符号是对符号串而非对字节计算的:因为编码器对最后一组做零扩展,解码同样的字符总能回到同一个值。这就是表中的校验值可以只凭编码列手工复现的原因。五个额外符号是 *、~、$、= 和 U,对应值 32、33、34、35、36,因此校验符号并不总是数字或字母。
z-base-32
z-base-32 保留 RFC 4648 Base32 的五比特打包,只改变三十二个字符的顺序。这个顺序让一个人最可能需要抄写的字符恰好是最容易写、最难混淆的那些。它没有填充,所以读者必须知道一个值应该有多少个符号;这就是一个优先为手写阅读设计的格式的代价。
Base58Check:一个版本字节、载荷、四个校验和字节
Base58 本身无法把输错的字符串和正确的区分开,因为其 58 个字符的几乎任意组合都是一个合法数字。Base58Check 通过把数据装进一个外壳来解决这个问题:一个版本字节,然后是载荷,然后是对前两部分连续做两次 SHA-256 取前四个字节。接收程序重新计算这四个字节,不一致就拒绝该字符串。版本字节告诉钱包它看到的是付款地址、脚本地址还是私钥。
转换器下方的生成器以十六进制输入版本字节和载荷并写出 Base58Check 字符串;校验器读回一个字符串,剥离四个校验和字节,重新计算它们,并报告找到的和期望的两个值。这里校验和错误意味着字符串被输错或篡改 — 绝不意味着载荷本身错误,因为载荷从未被解释。
常见误解
- “Base64 是加密。”不是。没有密钥也没有秘密;任何人都能还原输出。Base32 和 Base58 处于同样的位置,把一个值依次过三遍也不会增加任何保护。
- “Base58 字符串就是比特币地址。”只有当它同时通过 Base58Check 校验并携带接收软件认识的版本字节时才是。Base58 字符串还出现在许多其他场合,包括完全没有校验和的普通标识符。
- “三个 Base58 字母表可以互换。”它们用同样的 58 个字符、三种不同顺序,同样的字节会产生三个不同字符串。工具必须被告知用哪一个,而本页总是说明它用的是哪一个。
- “填充是值的一部分。”
= 字符只标记最后一组。两个仅填充不同的 Base32 字符串描述同样的字节,这就是解码器接受去掉填充的字符串的原因。
- “任何字符都行。”每个字母表都是固定集合。来自集合之外的字符没有值,所以解码器会停下来指出该字符及其位置,而不是去猜。
常见问题
为什么 Base32 用 2-7 而不是 0-9?因为 RFC 4648 选择字母表的原则是:只使用域名允许包含的字符,并且容易读出声。当自然排序更重要时,改用 0-9 A-V 的 Base32 Hex。
为什么 Base58 字符串经常以 1 开头?输入的每个前导零字节变成一个前导 1(Bitcoin 和 Flickr 字母表的首字符)。版本字节 0x00 就是一个零字节,所以大多数比特币主网地址恰好以一个 1 开头。
示例按钮加载什么?属于当前方案和当前方向的例子,绝不是固定文本。编码器得到该方案自己的示例文本 — Base32 与 Base32 Hex 用 RFC 4648 第 10 节向量、Crockford 的 12345、上文印出的 z-base-32 行 — 解码器得到所选字母表的编码字符串,这正是示例能双向使用的原因。三个 Base58 行有意使用同一文本,因此切换方案再点示例,可以并排看到同样 58 个字符的三种排序。勾选 Crockford 校验符号时,解码器拿到的是末尾带符号的值,这是能看到校验器接受一个值的唯一途径。
本页会把我的数据发到别处吗?不会。所有转换都在这个浏览器标签页中完成,页面不包含任何网络请求。这也是直接从磁盘打开文件也能用的原因。
存密钥该用哪一种?TOTP 和 HOTP 验证器密钥通常是 RFC 4648 字母表的 Base32,因为密钥需要手工输入。用接收软件要求的那一种,并且永远不要指望编码本身提供保密性。