Base58 编码详解与 Go 实现

在处理二进制数据时,我们经常需要将其转换成可读的字符串,比如生成地址、密钥、邀请码等。 常见方案有 Base64Hex 等,但在某些场景下,它们并不是最佳选择。 这时,Base58 就登场了。

什么是 Base58?

Base58 是一种基于 58 个字符的编码方式,它的设计目标是:

  • 避免易混淆字符0OlI
  • 不包含特殊符号+ / 等),适合直接用于 URL、文件名
  • 更适合人工抄写和阅读,降低输入错误率

它的字符集是:

123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz

可以看到,0OlI 等容易混淆的字符被剔除,没有 +/ 这类特殊符号。


为什么用 Base58?

假设你有一个用户需要手动输入邀请码、钱包地址或交易 ID:

  • 如果用 Base64,会出现 + / 等特殊字符,在 URL 中需要转义;
  • 如果用 Hex,数据会变得很长(每个字节要用两个字符表示);
  • 如果用 Base58,长度更短,可读性更高,错误率更低。

这也是为什么比特币、IPFS 等项目都选择了 Base58(或其变种 Base58Check)。


Base58 在实际项目中的应用

  • 比特币地址:Base58Check 编码,防止字符混淆并带有校验码
  • IPFS CID:文件内容 ID 使用 Base58 编码,更短且可直接用在命令行
  • 邀请码 / 短链:直接放在 URL 中,不需要额外转义

Go 语言 Base58 编码示例

这里用我开源的 Golang Base58 库来演示:

package main

import (
	"fmt"
	"log"

	"github.com/go-orz/base58"
)

func main() {
	data := []byte("Hello, Base58!")

	// 编码
	encoded := base58.EncodeToString(data)
	fmt.Println("Encoded:", encoded)

	// 解码
	decoded, err := base58.DecodeString(encoded)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("Decoded:", string(decoded))
}

运行结果:

Encoded: TcgsE5e9XJSrakNTEQQ
Decoded: Hello, Base58!

Base58 与 Base64 对比

特性Base64Base58
字符集64 个(含 + /)58 个(无易混淆字符)
URL 友好❌(需转义)
人工抄写友好
编码长度稍长
编解码速度略慢

如果你的数据主要是人类可读/可输入,Base58 更合适; 如果主要是机器传输,Base64 更高效。


项目地址

我开源了一个 Golang 的 Base58 编码库,简单、轻量、无第三方依赖, 欢迎 Star & Fork:

👉 https://github.com/go-orz/base58


💡 总结: Base58 解决了 Base64 在人工输入、URL 传递上的不便,特别适合区块链、邀请码、短链接等场景。 有了 Go 的实现,你可以在项目中轻松集成这种编码方式。