上传文件
  1. base64hub
  2. 其他进制编码
  3. Base45

Base45 编码与解码(RFC 9285)

输入文本即可得到 RFC 9285 Base45,它由二维码字母数字模式所能存储的 45 个字符组成。反转方向即可解码 Base45,例如 HC1: 健康证书中前缀之后的部分。

免费 无需注册,不限次数 本地 不上传任何内容 RFC 9285 RFC 中的全部示例均可复现 更新于 2026年10月27日
输入 0字节 0 B输出 0

在你的浏览器中处理。此页面无法将你的数据发送到任何地方: 我们如何确认

如何编码和解码 Base45

  1. 在 输入 · 文本 中输入或粘贴文本。Base45 字符串会显示在 输出 · Base45(RFC 9285) 中。
  2. 对于压缩后的字节等二进制数据,请先把 从 设为 Hex 或 Base64。
  3. 要解码,请在方向切换中点击 Base45(RFC 9285)→ 文本,然后粘贴字符串。如果结果是二进制数据(健康证书就是如此),请在 到 中选择 Hex 或 Base64。
  4. 复制输出 会完整保留空格。保存字节 会把解码后的字节下载为文件。

Base45 的工作原理

RFC 9285 每次取输入的两个字节。每对字节是一个 0 到 65535 之间的数 n,写成三个 45 进制数字 c、d、e,满足 n = c + d × 45 + e × 45²,低位在前。最后剩下的单个字节变成两个数字。字母表就是按顺序排列的二维码字母数字字符集:

0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:

RFC 中的示例,本工具全部可以复现:

输入Base45
ABBB8
Hello!!%69 VD92EX0
base-45UJCLQE7W581
ietf!QED8WEX0

解码时会检查两件宽松的解码器可能跳过的事:长度为 3n + 1 的字符串不可能由任何输入生成;值超过 65535 的分组(例如 GGW 或 ZZZ)超出了范围。两种情况都会报错。

为什么 Base45 适合二维码

纸面上看,Base45 似乎很浪费:每 2 个字节用 3 个字符,开销 50%,比 Base64 的 33% 还多。差别在于二维码存储文本的方式。在字母数字模式下,二维码把两个这样的字符装进 11 个比特。因此三个 Base45 字符占用 16.5 比特,承载 16 比特数据,开销约为 3%。

Base64 无法使用字母数字模式,因为它需要小写字母。它只能使用每个字符 8 比特的字节模式,在二维码中的开销为 33%。对于相同的数据,Base45 生成的二维码更小,或者能容纳更多内容。

解码欧盟数字新冠证书(HC1:)

欧盟数字新冠证书的二维码中是一个以 HC1: 开头的字符串。载荷是分层构建的,本页处理其中一层:

  1. 去掉 HC1: 前缀。H、C、1 和 : 都是有效的 Base45 字符,所以如果保留前缀,它会被当作数据解码,后面的内容全部出错。
  2. 在这里对剩余部分做 Base45 解码,并把 到 设为 Base64。
  3. 解压结果。它是 zlib 数据,以字节 78 开头(Base64 中为 eJ 或 eN)。把 Base64 粘贴到 gzip 与 zlib 解码器中。
  4. 解析 CBOR。解压后的字节是 CBOR 格式的 COSE_Sign1 结构:一个头部、包含证书字段的载荷,以及一个签名。这需要 CBOR 解码器,本站没有提供。

解码可以看到内容,但不会验证签名。要检查证书是否真实,需要签发国的公钥和 COSE 验证工具。

在 Python 中使用 Base45

Python 标准库中没有 Base45 模块。下面的编码器直接按照 RFC 实现:

ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:"

def b45encode(data: bytes) -> str:
    out = []
    for i in range(0, len(data) - 1, 2):
        n = data[i] * 256 + data[i + 1]
        c, n = n % 45, n // 45
        d, e = n % 45, n // 45
        out += ALPHABET[c], ALPHABET[d], ALPHABET[e]
    if len(data) % 2:
        c, d = data[-1] % 45, data[-1] // 45
        out += ALPHABET[c], ALPHABET[d]
    return "".join(out)

b45encode(b"ietf!")    # 'QED8WEX0'

PyPI 上的 base45 包提供了编码和解码两个方向。更多 Python 字节处理见 Python 页面。

常见问题

为什么 Base45 输出中有空格?

空格是二维码字母数字字符集中的 45 个字符之一,所以它在 Base45 中是一个普通的数字,值为 36。Hello!! 编码为 %69 VD92EX0。复制时请保留空格,也不要让表单或 shell 把它们去掉。

能在这里解码欧盟数字新冠证书吗?

可以完成一部分。本页负责 Base45 这一步。之后的数据是签名 COSE 结构中经过 zlib 压缩的 CBOR,需要先解压再用 CBOR 解码器处理;具体步骤见本页。

Base45 可以放进 URL 吗?

不行。空格、%、+ 和 / 都在字母表中,而它们在 URL 中都有特殊含义。请对字符串做百分号编码,或者在 URL 中使用 Base64URL。

为什么我的 Base45 字符串被拒绝?

有效的 Base45 长度为 3n 或 3n + 2 个字符,且每个 3 字符分组的值不能超过 65535。长度为 3n + 1,或出现 GGW 这样的分组,都会报错。常见原因是残留了 HC1: 前缀。