Private Key Tools

Base58Check 编码 / 解码

把任意 1…、3…、5…、K… 字符串拆开:版本字节、载荷主体、4 字节双 SHA256 校验和,以及它究竟能不能通过校验。也可以反过来 —— 给它一个十六进制载荷,返回带校验和的 Base58Check 字符串。

解码过程从不信任输入:校验和会被重新计算并如实报告。
解码模式:Base58 字符串,例如 146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT(地址)或 KwVYL77Lcs1ckM39NvGjrtfKhU4KKdR2iB9Wq2FSMN6rbGK5tVqG(WIF)。编码模式:已经包含版本字节的十六进制载荷,例如 0021f57b6debcfc5b67182dfb4af1641f0a8189012。
还没有输入

请在上方输入内容后点击「转换」。不知道填什么?点「填入示例」即可载入占位符里的演示数据。

技术原理详解

本页做什么

比特币里所有 1…、3…、m…、2…、5…、 K… 字符串背后都是 Base58Check。它就是一次进制转换,外挂一个校验和:

Base58Check(载荷) = Base58( 载荷 ‖ SHA256(SHA256(载荷))[0..4] )
载荷(版本 ‖ 内容)→ SHA-256→ SHA-256→ 前 4 字节→ 载荷 ‖ 校验和→ 转成 58 进制→ 146ZNjH7…

解码模式接收一个成品字符串,把它拆开:版本字节、载荷主体、校验和,以及校验和是否真的通过。 编码模式接收一个十六进制载荷,返回对应的 Base58Check 字符串,并显示它追加的校验和。

1. Base58 字母表,以及为什么少了四个字符

Base58 不是任何标准。它就是 Base64 去掉碍事的符号,再拿掉六个容易抄错的字符。比特币使用的字母表是:

下标字符数量
0 – 81234567899 个数字
9 – 32ABCDEFGHJKLMNPQRSTUVWXYZ24 个大写字母
33 – 57abcdefghijkmnopqrstuvwxyz25 个小写字母
合计58 个字符

Base64 舍弃了 + 和 /,因为它们会破坏复制粘贴与 URL 处理。比特币版本又刻意多去掉了四个:

被去掉原因
0(数字零)在大多数字体里和 O 几乎一样,也容易与小写 o 混淆
O(大写 O)同一个问题的另一面
I(大写 i)在无衬线与等宽字体中与小写 l 完全相同
l(小写 L)在很多字体里与数字 1 完全相同

注意哪些留下了:小写 i 和小写 o 都在字母表里。规则并不是「不要形近字母」, 而是「绝不留下会互相混淆的两个字符」:1 之所以保留,是因为它现在是唯一的竖线字形; i、o 之所以保留,是因为与它们形近的那两个才是被删掉的。收益是:抄错的地址更可能 被校验和拦住,而不是悄悄变成一个合法但错误的地址。

2. 前导 1 的约定

进制转换就是把一个数变成一串数字。它无法表达前导零字节,因为前导零不携带任何数值信息: 0x0021 与 0x21 是同一个数。因此比特币另立了一条明确规则:

每个前导 0x00 字节对应一个前导字符 1,然后才是剩余数字的 58 进制表示
Base58 字符串解码后的字节说明
100一个零字节,没有数值部分
110000两个零字节
120001一个零字节,然后是数值 1
z39没有前导零;z 下标是 57 —— 一位字符能表示的最大值

这就是主网 P2PKH 地址以 1 开头的原因:它的载荷第一个字节是版本字节 0x00,于是产生 一个字面字符 1,而它不属于进制转换出来的数字。同样地,25 字节的 P2PKH 地址永远是 34 个 字符:1 个 1 给版本字节,剩下 24 字节大约需要 33 个字符。

用一个极端例子就能直接看到这条规则:载荷 0x00 后面跟二十个零字节,编码结果是 1111111111111111111114oLvT2 —— 21 个前导 1,每个零字节一个,后面 4 个普通 base58 字符代表那 4 字节校验和。

3. 校验和:能查出什么,不能做什么

编码前会在载荷后追加 4 字节双 SHA-256,任何解码器都会重新算一遍:

校验和 = SHA256( SHA256(载荷) )[0..3]   (4 字节 = 232 = 4294967296 种取值)
错误能否查出原因
单个字符打错能,概率 1 − 2−32载荷变了,重算的校验和就变了;只有约四十亿分之一的巧合会通过
两个及以上字符打错同样概率这里不对错误形态做任何假设,所以保证是概率性的,不是绝对的
字符顺序颠倒同样概率与某些基于编码的校验和不同,Base58 的顺序敏感性来自数值本身,而不是逐位相加
出现非法字符(0、O、I、l)必然查出这些字符压根不在字母表里,解码直接失败
字符串被截断通常能 —— 或者直接报「太短」解码不足 5 字节时,连 4 字节校验和都装不下
一个指向别的地址的合法字符串查不出校验和防的是手误,永远防不了被另一个格式正确的字符串替换
只能检测,不能纠正

校验和失败时,你得到的全部信息就是:这个字符串是错的。校验和是哈希,是一个看起来随机 的 4 字节摘要,没有任何代数结构 —— 因此无法从「期望 cbd7667e、实得 cbd76695」 反推出「第 27 个字符可疑」。唯一正确的做法是重新复制或重新扫描原字符串。靠猜就是丢币的开始;BIP173 也正是 因此指出,Base58Check 这类设计「没有任何错误检测保证」,只有很小的随机碰撞概率。

作为对照,bech32 地址做了相反的设计选择:它的 BCH 校验和保证能检测任何影响至多 4 个字符的错误, 甚至还能算出一小组候选错误位置 —— 见 Bech32 / Bech32m。

4. 版本字节:载荷的第一个字节就是类型标签

除校验和之外的一切都是不透明字节;它们的含义完全来自版本字节,也就是载荷的第一个字节。本页支持 六种:

版本字节含义载荷长度(不含校验和)开头字符
0x00P2PKH 地址,主网21 字节(1 + hash160)1
0x05P2SH 地址,主网21 字节(1 + 脚本哈希)3
0x6FP2PKH 地址,测试网21 字节m 或 n
0xC4P2SH 地址,测试网21 字节2
0x80WIF 私钥,主网33 字节(非压缩)或 34 字节(压缩,末尾 0x01)5,或 K / L
0xEFWIF 私钥,测试网33 或 34 字节9 或 c

有两点值得记牢。第一,首字符不是被选出来的,而是版本字节与载荷长度共同导致的结果;所以「以 1 开头的地址」与「版本字节 0x00」说的完全是同一件事。第二,版本字节没有任何东西 为它背书:一个字符串要么自洽、要么不自洽,但没人拦得住你把一个格式正确的测试网地址称作主网地址。同时支持 两个网络的钱包必须自己校验版本字节。

5. 需要多少字符?58N 的算术

每个 Base58 字符携带 log2(58) ≈ 5.858 位,因此每个字节大约需要 1.3657 个字符:

字节数(载荷 + 4 字节校验和)位数log58(2位数)字符数示例
25 字节20034.14134,最多 35146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT(34)
37 字节29650.529515HssbguBnjbaUVZCsH9YuzUG7T4vYQf51iiodi4izdVy6aVNekU(51)
38 字节30451.89552KwVYL77Lcs1ckM39NvGjrtfKhU4KKdR2iB9Wq2FSMN6rbGK5tVqG(52)

作为参考,5833 = 15599970876632771988160814054146447252125923204784443097088, 5834 = 904798310844700775313327215140493940623303545877497699631104;而 2192 = 6277101735386680763835789423207666416102355444464034512896,2200 = 1606938044258990275541962092341162602522202993782792835301376。由于 2192 < 5834,24 字节永远装得进 34 个字符 —— 这就是 P2PKH 地址里那个 1 加上 33 个字符。

那地址有没有可能变成 35 个字符?从算术上说可以:当 25 字节载荷的数值达到 5834 时就需要第 35 个字符,而这要求首字节不小于 0x90。上表里的每个版本字节都远低于此,所以真实的比特币 1…、3… 地址永远是 34 个字符。(这里实测过:载荷以 0x8F 开头得到 34 个 字符,以 0x90 开头则得到 35 个。)

6. Base58、Base58Check、Bech32 对比

Base58CheckBech32(v0)Bech32m(v1+)
字母表58 个字符,大小写混合32 个字符,仅小写32 个字符,仅小写
校验和双 SHA-256 的 4 字节6 个字符,BCH 码,常量 16 个字符,BCH 码,常量 0x2bc830a3
错误检测概率性(1 − 2−32)保证检测 ≤ 4 个错误字符保证检测 ≤ 4 个错误字符
类型标签载荷内部的版本字节数据部分的第一个值 = witness 版本数据部分的第一个值 = witness 版本
大小写区分大小写,两种都合法禁止大小写混用禁止大小写混用
用途P2PKH、P2SH、WIFP2WPKH、P2WSHP2TR 及未来版本

7. 实例演算:解码示例 P2PKH 地址

下表就是 146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT 的真实结构,与解码模式的输出完全一致:

步骤值
Base58 字符串146ZNjH7XTXnMd1ofe3z7CL2i8WM7N2UqT(34 个字符)
解码后的字节(载荷 ‖ 校验和)0021f57b6debcfc5b67182dfb4af1641f0a8189012cbd7667e(25 字节)
载荷0021f57b6debcfc5b67182dfb4af1641f0a8189012(21 字节)
版本字节00 → P2PKH,主网
载荷主体21f57b6debcfc5b67182dfb4af1641f0a8189012(20 字节 = 一个 hash160)
载荷的 SHA-256705cbbd9867cfeb7d5b0356c9bafe09bb2a50c40e69c7ee0535cfcbf987db587
载荷的双 SHA-256cbd7667ea989f5994e7e12439589085e0eda7572712b71cf66374edff592182f
校验和(字符串最后 4 字节)cbd7667e —— 与上面的前 4 字节一致,校验通过
解读P2PKH,主网,支付给 hash160 21f57b6d…89012

P2SH 地址形状完全相同,只是版本字节不同:3DZT76KyKyc5zkzvLugP8umgt4RPY4XPQw 解码得到载荷 05823333d5fd23a83661e8e47629552c4a5bfc8b6e(版本 05,校验和 acbfef44), 其中那 20 字节主体是某个 redeemScript 的哈希,而不是公钥的哈希。

8. 实例演算:解码示例 WIF

步骤值
Base58 字符串KwVYL77Lcs1ckM39NvGjrtfKhU4KKdR2iB9Wq2FSMN6rbGK5tVqG(52 个字符)
解码后的字节800824c314772b2c2859c889471390a36bf66e53a1ca1642f96f0f2c9307a171ca013a0a0417(38 字节)
载荷800824c314772b2c2859c889471390a36bf66e53a1ca1642f96f0f2c9307a171ca01(34 字节)
版本字节80 → WIF,主网
载荷主体0824c314…a171ca(32 字节私钥)后面跟着 01
末尾那个 01「压缩公钥」标志 —— 正是它的存在让这个地址族产生 K…/L… 形式的 WIF
双 SHA-256 校验和3a0a0417ffa98881ccdd0c7b283639584e0e909389f6bfbbdbac54547d2b732d → 前 4 字节 3a0a0417,与字符串一致
对照5HssbguBnjbaUVZCsH9YuzUG7T4vYQf51iiodi4izdVy6aVNekU 是 51 个字符:版本字节相同,但没有末尾标志,因此对应非压缩公钥

不看那个 01 标志,你就无法判断这把私钥控制哪一个地址 —— 而这正是人们「弄丢」其实还在自己手里的 币的最常见原因。这个标志存在编码后的字符串里,不在私钥里。

9. 实例演算:编码

编码模式输入载荷 00751e76e8199196d454941c45d1b3a323f1433bd6(BIP173 标准测试用的 hash160, 版本字节 00),得到:

步骤值
载荷00751e76e8199196d454941c45d1b3a323f1433bd6(21 字节)
双 SHA-256510d1634d943109b69da527ef5948106f22b655fb5193b4e9ef7e4dcd342d245
追加的校验和510d1634
参与进制转换的字节00751e76e8199196d454941c45d1b3a323f1433bd6510d1634(25 字节)
Base58Check 结果1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH(34 个字符)

把结果再送进解码模式,会还原出原来的 21 字节载荷并且校验通过 —— 这正是这种编码的意义:字符串自己带着 完整性证明。

10. 安全须知与常见错误

不要使用任何「捡到」的 WIF

本页会解码你粘贴的任何 Base58Check 字符串,包括私钥。任何见过这个字符串的人都拥有那些币。如果一个 「捡到的」或「泄漏的」WIF 是真的,那么在你看到它的那一刻,余额就已经没了。

11. 它在链条中的位置

12. 速查表

项目值
字母表123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz
被排除的字符0、O、I、l
每字符位数log2(58) ≈ 5.858
校验和SHA256(SHA256(载荷)) 的前 4 字节
校验和空间232 = 4294967296 种
前导零字节每个 0x00 字节对应一个字面字符 1
P2PKH / P2SH 地址长度恒为 34 个字符
WIF 长度非压缩 51 个字符,压缩 52 个字符
能纠错吗不能 —— 只能检测