Base64 只是最流行的二进制编码方案,但它不是唯一的。Hex 编码更直观、Base58 去掉了易混字符、Base85 更高效。本文把四种编码方案放在一起对比,搞清楚每种方案适合什么场景。
四种编码方案总览
| Hex | 16 | 0-9a-f | 2x | 哈希值展示、调试 |
| Base32 | 32 | A-Z2-7 | 1.6x | RFC 4648、OTP 密钥 |
| Base64 | 64 | A-Za-z0-9+/ | 1.33x | 通用二进制转文本 |
| Base58 | 58 | 去 0/O/I/l 等易混字符 | 1.37x | 比特币地址、短链接 |
| Base85 | 85 | ASCII 33-117 | 1.25x | PDF、PostScript |
Hex 编码
Hex 编码把每个字节转成 2 个十六进制字符。最直观、最易于调试。
// Node.js
const buf = Buffer.from('Hello', 'utf-8')
console.log(buf.toString('hex')) // 48656c6c6f
// 浏览器
const bytes = new TextEncoder().encode('Hello')
const hex = Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('')
console.log(hex) // 48656c6c6f
优点:编码结果可读性强,每字节对应 2 个字符,一眼能看出原始字节值;不区分大小写;无 padding 问题。
缺点:膨胀率 2 倍,数据翻倍。传输 1MB 的数据编码后变 2MB。
适用场景:MD5/SHA 哈希值展示(deadbeef)、调试日志、密钥指纹显示。
Base32 编码
Base32 用 32 个字符(A-Z + 2-7),每 5 字节(40 位)编码为 8 个字符。
import base64
# 编码
encoded = base64.b32encode(b'Hello World').decode('ascii')
print(encoded) # JBSWY3DPEBLW64TMMQ======
# 解码
decoded = base64.b32decode('JBSWY3DPEBLW64TMMQ======')
print(decoded) # b'Hello World'
优点:
- 字符集小,只有大写字母和数字 2-7,不区分大小写
- 排除了容易混淆的字符(0/O、1/I)
- 错误检测能力强,适合人工输入
缺点:膨胀率 1.6 倍,比 Base64 大。
适用场景:TOTP/HTOP 一次性密码的密钥编码(Google Authenticator)、RFC 4648 规范场景、需要人工输入或抄录的场景。
Base58 编码
Base58 是比特币社区设计的编码方案,从 Base64 的字符表中去除了容易混淆的字符:
去除的字符:0(零)、O(大写 O)、I(大写 i)、l(小写 L)、+、/
// Base58 编码表
const BASE58_CHARS = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
function encodeBase58(bytes) {
let num = BigInt(0)
for (const b of bytes) {
num = num * 256n + BigInt(b)
}
let result = ''
while (num > 0) {
const remainder = num % 58n
result = BASE58_CHARS[Number(remainder)] + result
num = num / 58n
}
// 前导零字节处理
for (const b of bytes) {
if (b === 0) result = '1' + result
else break
}
return result
}
console.log(encodeBase58(Buffer.from('Hello World', 'utf-8')))
// JxF12TrwUP45BMd
优点:
- 去除易混字符,适合人工抄写和口播
- 不含 +/=,URL 安全
- 比特币地址、IPFS Hash 等标准格式
缺点:
- 编码解码涉及大整数运算,性能不如 Base64
- 膨胀率约 1.37 倍,略大于 Base64
- 不同实现可能有不同字符表(Base58Check、Base58Flickr 等)
适用场景:比特币/区块链地址、短链接 ID、需要人工输入的场景。
Base85 编码
Base85 用 85 个可打印 ASCII 字符(33-117),每 4 字节编码为 5 个字符,膨胀率仅 1.25 倍。
import base64
# Base85 编码(ASCII85)
encoded = base64.b85encode(b'Hello World')
print(encoded) # b'87cURD]j7BEbo80'
# 解码
decoded = base64.b85decode(b'87cURD]j7BEbo80')
print(decoded) # b'Hello World'
优点:膨胀率最低(1.25x),编码效率高。
缺点:
- 字符集包含非字母数字字符(如 !#$%&()*+,-./),在某些场景不安全
- 兼容性差,各实现差异大(ASCII85、ZeroMQ Z85、IPv6 Base85)
适用场景:PDF 文件内部编码、PostScript 文件、需要最高编码效率的场景。
效率对比
同一段数据(100 字节)用不同方案编码:
| Raw | 100 字节 | 1.0x | – |
| Hex | 200 字符 | 2.0x | +50% |
| Base32 | 160 字符 | 1.6x | +20% |
| Base58 | ~138 字符 | 1.38x | +3.7% |
| Base64 | 136 字符 | 1.33x | 基准 |
| Base85 | 125 字符 | 1.25x | -8% |
Base85 最节省空间,但兼容性最差。Base64 是效率和通用性的最佳平衡点。
选型决策
数据需要人工输入或抄录吗?
├── 是 → Base32(OTP 密钥)或 Base58(区块链地址)
└── 否 → 对编码效率要求高吗?
├── 是 → Base85(PDF/PostScript 内部)
└── 否 → 需要调试可读性吗?
├── 是 → Hex(哈希值、调试日志)
└── 否 → Base64(通用方案)
各语言编码方案支持
| JavaScript | 手动 | 手动 | btoa/atob | 需第三方库 | 需第三方库 |
| Python | binascii | base64.b32 | base64.b64 | 需第三方库 | base64.b85 |
| Java | 手动 | 手动 | java.util.Base64 | 需第三方库 | 需第三方库 |
| Go | encoding/hex | 手动 | encoding/base64 | 需第三方库 | 需第三方库 |
| Rust | hex crate | base32 crate | base64 crate | bs58 crate | 需第三方库 |
Base64 是唯一所有语言标准库都支持的编码方案——这也是它最流行的根本原因。
在线实践
对比编码结果最直观的方式是用同一段数据编码看看。可以在 盘子工具站 Base64 编码工具 上做这种对比——输入 Hello World,获得 Base64 编码结果 SGVsbG8gV29ybGQ=(16 字符)。你可以把同样的数据用 Hex 编码(48656c6c6f20776f726c64,22 字符),直观感受膨胀率的差异。
如果你想看 Base58 在实际场景中的应用,可以在 blockchain.com 上查看一个比特币地址——那串以 1 或 3 开头的字符就是 Base58 编码的。对比同一段公钥数据的 Base64 编码和 Base58 编码,你会发现 Base58 更短且没有易混字符。
工具的文件转 Base64 功能也适合做对比——上传同一文件,分别用不同方案编码,对比编码后字符串的长度。所有编码在浏览器本地完成,不上传服务器。




