如何将 Base64 转换为 Base58
- 把 Base64 字符串粘贴到 输入 · Base64。标准字符和 URL 安全字符都可以,缺失的
=填充、换行和data:前缀也没问题。 - 在 输出 · Base58 中查看结果。
- 如果目标不是比特币风格的 Base58,在输出下方选择 字母表。Flickr 和 Ripple 使用同样的 58 个字符,只是顺序不同。
- 点击 复制输出,或点击方向切换中的 Base58 → Base64 转回去。Base58 转 Base64 页面默认就是这个方向。
转换经由原始字节完成:先解码 Base64,再把字节编码为 Base58。不会增加或删除任何内容,所以 32 字节的密钥仍然是 32 字节。
示例
| Base64 | Base58 | 含义 |
|---|---|---|
SGVsbG8= | 9Ajdvzr | 文本 Hello |
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= | 11111111111111111111111111111111 | 32 个零字节:Solana System Program |
Bt324ddloZPZy+FGzut5rBy0he1fWzeROoz1hX7/AKk= | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA | Solana SPL Token 程序 ID |
Bt324ddloZPZy-FGzut5rBy0he1fWzeROoz1hX7_AKk | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA | 同一个密钥,URL 安全且无填充的 Base64 |
最后两行是同样 32 个字节的两种 Base64 写法,所以得到的 Base58 也相同。
用 SHA-256 摘要构造 IPFS CIDv0
CIDv0 是 multihash 的 Base58:先是字节 12(SHA-256)和 20(长度 32 字节),然后是摘要。很多工具以 Base64 输出 SHA-256 摘要,只转换摘要本身是得不到 Qm… 字符串的:
| 字节 | Base64 | Base58 |
|---|---|---|
| 仅摘要 | JiqGtnblhp7dXRrfj/0B1inDFUv96uz8jPoNkOCILYo= | 3Zz6yE7jDUVDb6doCEWrK58or4X2TmTLBiJeyWY4NHvq |
12 20 + 摘要 | EiAmKoa2duWGnt1dGt+P/QHWKcMVS/3q7PyM+g2Q4Igtig== | QmQudp5N7EzTxrBk3yESEKyEroMYNd7R22G2KWffwNZyzq |
第二个 Base64 字符串开头的 EiA 就是编码后的 12 20 头,所以 Base64 形式的 multihash 很容易认出来。要自己加上这个头,先用 Base64 转 Hex 转换摘要,在前面加上 1220,再到 Base58 页面 中把 从 设为 Hex,对这段 hex 进行编码。
这只适用于你已经拿到 IPFS 计算出的摘要的情况。IPFS 计算哈希的对象是文件的 UnixFS 块,而不是原始文件,所以对文件运行 sha256sum 得不到它的 CID。
长度:Base64 与 Base58
| 字节数 | Base64 | Base58(随机数据) |
|---|---|---|
| 16 | 24 | 21 或 22 |
| 20 | 28 | 26 到 28 |
| 32 | 44 | 43 或 44 |
| 64 | 88 | 87 或 88 |
Base64 的长度只取决于字节数。Base58 的长度还取决于数值本身,这就是 Solana 地址长度在 32 到 44 个字符之间变化的原因。不要靠精确长度来校验 Base58。
在 JavaScript 中完成同样的转换
Node.js 原生支持 Base64 解码;Base58 部分需要用到 BigInt:
const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
function base64ToBase58(b64) {
const bytes = Buffer.from(b64, "base64");
let n = BigInt("0x" + (bytes.toString("hex") || "0"));
let out = "";
while (n > 0n) {
out = ALPHABET[Number(n % 58n)] + out;
n /= 58n;
}
for (const b of bytes) {
if (b !== 0) break;
out = "1" + out;
}
return out;
}
base64ToBase58("Bt324ddloZPZy+FGzut5rBy0he1fWzeROoz1hX7/AKk=");
// 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
Buffer.from(…, "base64") 也接受 URL 安全的输入。该函数依赖 Node 的 Buffer;Node.js 中的 Base64 有更详细的介绍。
常见问题
能不解码成字节,直接把 Base64 转成 Base58 吗?
无法逐字符转换。Base64 按固定的 6 位一组映射,而 Base58 把所有字节当作一个大数,所以任何转换器(包括本页)都要先把 Base64 解码成字节,再对这些字节重新编码。
为什么 Base58 结果有时比 Base64 短?
Base58 没有填充,每个前导零字节只占一个字符。32 个字节的 Base64 永远是 44 个字符(含 =),Base58 则是 43 或 44 个,只有全部字节为零时才是 32 个。
Solana 用的是哪种 Base58 字母表?
比特币字母表,也是这里的默认值。如果需要 Flickr 或 Ripple 字母表,可以在 字母表 中选择。
为什么我的 Base58 输出不是以 Qm 开头?
Qm 来自 2 字节的 multihash 头 12 20。如果你的 Base64 只包含 32 字节的 SHA-256 摘要,需要先在前面加上这两个字节,具体做法见本页。