如何编码为 Base58
- 在 输入 · 文本 中输入或粘贴文本。Base58 字符串会随着输入实时显示在 输出 · Base58 中。
- 在输出下方选择 字母表:Bitcoin(默认,IPFS 和 Solana 也用它)、Flickr 或 Ripple。
- 要编码原始字节而不是文本,请把 从 设为 Hex 或 Base64,然后以该形式粘贴字节。公钥或哈希几乎总是字节,而不是文本。
- 在方向切换中点击 Base58 → 文本 进行解码,或者打开以 hex 显示字节的 Base58 解码器。
Base58 编码的原理
Base58 不像 Base64 那样把输入切成固定的比特组。它把所有字节读作一个大端序的大数,用 58 进制写出这个数,然后为每个前导零字节添加一个 1。所以改动一个字节就可能改变整个字符串,而且长度取决于数值,而不仅仅取决于字节数。
把数据当作一个数字处理的代价会随大小迅速增长,所以本工具把 Base58 输入限制在 64 KB。这远远超过任何密钥、哈希或地址所需的长度。
三种 Base58 字母表
三种字母表使用相同的 58 个字符(数字和字母,去掉 0、O、I、l),只是顺序不同:
| 字母表 | 开头 | Hello | 0x00 0x00 0x01 |
|---|---|---|---|
| Bitcoin | 123456789ABC… | 9Ajdvzr | 112 |
| Flickr | 123456789abc… | 9aJCVZR | 112 |
| Ripple | rpshnaf39wBU… | 9wjdvzi | rrp |
Flickr 互换了大小写,Flickr 用它生成照片短链接。Ripple 的字母表以 r 开头,所以版本字节为零的 XRP Ledger 地址以 r 开头,就像比特币地址以 1 开头一样。用错字母表解码通常不会报错,但会得到不同的字节,所以当某个值对不上时,先检查字母表。
前导零与开头的 1
由于 Base58 把数据当作数字处理,开头的零字节本会消失。这种格式通过为每个零字节写一个 1 来保留它们:
| 字节(hex) | Base58 |
|---|---|
00 | 1 |
00 00 | 11 |
00 01 | 12 |
ff | 5Q |
31 × 00,然后是 ff | 11111111111111111111111111111115Q |
32 × 00 | 11111111111111111111111111111111 |
最后一行是一个真实的地址:三十二个 1 就是 Solana System Program,它的公钥是 32 个零字节。前导零是手写 Base58 代码最容易出错的地方,丢掉它们的编码器生成的字符串会解码出更少的字节。
Base58 用在哪里
- 比特币地址和 WIF 密钥。传统地址(
1…、3…)和 WIF 私钥(5…、K…、L…)都是 Base58Check:带版本字节和校验和的 Base58。Bech32 地址(bc1…)是另一种编码。 - IPFS CIDv0。
Qm…标识符是 34 字节 multihash 的普通 Base58:12(SHA-256)、20(长度 32 字节)以及摘要。正是12 20这个头部让每个 CIDv0 都以Qm开头。 - Solana。地址和公钥是 32 字节的 Base58(32 到 44 个字符);交易签名是 64 字节的 Base58(最多 88 个字符)。
在 Python 中使用 Base58
Python 标准库中没有 Base58。这个算法短到可以直接写出来,下面的版本处理了前导零:
ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
def b58encode(data: bytes) -> str:
n = int.from_bytes(data, "big")
out = ""
while n:
n, r = divmod(n, 58)
out = ALPHABET[r] + out
zeros = len(data) - len(data.lstrip(b"\0"))
return "1" * zeros + out
b58encode(b"Hello") # '9Ajdvzr'
b58encode(bytes(32)) # '11111111111111111111111111111111'
在生产代码中,PyPI 上的 base58 等维护良好的包还支持 Base58Check。通用的 Python 编码写法见 Python 页面。
常见问题
Base58 去掉了哪些字符?
Base58 是 Base62 去掉四个易混淆的字符:0(零)、O(大写 o)、I(大写 i)和 l(小写 L)。它也没有 +、/ 或 =,所以 Base58 字符串双击就能整个选中,放进 URL 也不需要转义。
为什么 Base58 输出以 1 开头?
每个 1 代表输入中的一个前导零字节。普通的数字会丢掉这些零,所以 Base58 把它们显式写出来。比特币地址以 1 开头,是因为它们的版本字节是 0x00。
Base58 和 Base58Check 是一回事吗?
不是。Base58Check 是对附加了 4 字节双重 SHA-256 校验和的载荷做 Base58 编码。比特币地址和 WIF 私钥使用它;Solana 地址和 IPFS CIDv0 使用普通 Base58。带校验和的形式请用 Base58Check 工具。
Base58 比输入长多少?
对随机数据约长 37%(log 256 / log 58 ≈ 1.366),比 Base64 的 33% 略多。确切长度取决于数值本身:32 个随机字节得到 43 或 44 个字符,而 32 个零字节得到 32 个 1。