# Base94 编码：紧凑数据表示

> 了解 Base94 编码——与 Base64 的区别、完整可打印 ASCII 字符集、压缩效率和实际应用场景。

Canonical: https://hsmkit.com/zh/guides/base94-encoding-guide/

Last updated: 2026-05-21

Base94 是一种二进制转文本编码，使用所有 94 个可打印 ASCII 字符（不包括空格）。它比 Base64 实现更高的数据密度，当您需要尽可能紧凑地将二进制数据编码为可打印 ASCII 时非常有用。本文解释 Base94 的工作原理和使用场景。

## 什么是 Base94？

Base94 使用从 `!`（0x21）到 `~`（0x7E）的 94 个可打印 ASCII 字符，不包括空格。这是可用的可打印、非空白 ASCII 字符的最大数量：

```
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
```

每个 Base94 字符表示大约 **6.55 位**数据（log₂(94) ≈ 6.55），而 Base64 是 6 位。这使 Base94 比 Base64 有大约 **22% 更好的密度**。

## Base94 编码工作原理

Base94 将输入视为大整数并转换为 94 进制：

### 编码过程

1. 将输入字节转换为大整数
2. 重复除以 94，记录余数
3. 将每个余数映射到 Base94 字符
4. 余数（按相反顺序）组成编码字符串

```
输入字节: [0x48, 0x65, 0x6C] ("Hel")
作为整数: 4,610,412

4610412 ÷ 94 = 49047 余 14 → '6'   （位置 14）
49047 ÷ 94 = 521 余 73 → 'o'       （位置 73）
521 ÷ 94 = 5 余 51 → '7'           （位置 51）
5 ÷ 94 = 0 余 5 → '%'              （位置 5）

结果: "%7o6" （反转的余数）
```

注意：确切的字符映射因实现而异。上面的示例使用从 `!` 开始的标准可打印 ASCII 范围。

## Base94 vs Base64 vs 十六进制

| 编码 | 字符数 | 每字符位数 | 开销 | 使用场景 |
|------|--------|-----------|------|---------|
| 十六进制 | 16 | 4 | 100% | 密码学值、调试 |
| Base64 | 64 | 6 | 33% | 通用二进制转文本 |
| Base94 | 94 | ~6.55 | ~22% | 最大密度文本编码 |

### 密度比较

编码 32 字节（256 位）数据：

| 编码 | 输出长度 | 字符数 |
|------|---------|--------|
| 十六进制 | 64 | 64 |
| Base64 | 44（带填充） | 44 |
| Base94 | ~39 | ~39 |

与 Base64 相比，Base94 每 32 字节节省约 5 个字符。对于更大的数据，节省会累积。

## 字符集

Base94 使用可打印 ASCII 字符，但确切范围可能有所不同：

### 标准范围（0x21 - 0x7E）
- 字符：`!` 到 `~`
- 不包括：空格（0x20）
- 最常见的实现

### 自定义范围
某些实现排除了在特定上下文中造成问题的字符：
- URL 不安全字符：`<`、`>`、`"`、`{`、`}`、`|`、`\`、`^`、`` ` ``
- Shell 特殊字符：`$`、`` ` ``、`\`、`"`、`'`
- 标记字符：`<`、`>`、`&`

始终检查您的特定 Base94 实现使用哪个字符集。

## 与其他编码的比较

### Base64

- **优点**：标准化（RFC 4648），广泛支持，有 URL 安全变体
- **缺点**：33% 开销
- **使用场景**：兼容性重要，需要标准编码

### Base94

- **优点**：~22% 开销，最大密度
- **缺点**：未标准化，实现较少，可能有字符集问题
- **使用场景**：密度关键，受控环境

### Base85（Ascii85）

- **优点**：25% 开销，比 Base64 好
- **缺点**：不同实现使用不同字符集（btoa、RFC 1924）
- **使用场景**：需要比 Base64 更好的密度但标准 Base94 不可用

### 十六进制

- **优点**：通用、简单、可调试
- **缺点**：100% 开销
- **使用场景**：密码学值、调试、人类可读性

## 实际应用场景

### 数据序列化

当为只接受可打印文本的系统序列化二进制数据时：
- 配置文件
- 数据库文本字段
- 日志条目
- 有大小限制的 API 响应

### 紧凑令牌

生成紧凑令牌用于：
- 会话标识符
- API 密钥
- 短 URL
- QR 码有效载荷

### 嵌入式系统

在内存受限的环境中，每个字节都很重要：
- 固件更新有效载荷
- 串行通信协议
- IoT 设备消息

### 密码学材料

更紧凑地编码密码学值：
- 配置文件中的密钥材料
- Nonce/IV 值
- 哈希摘要

## 实现注意事项

### 填充

与 Base64 不同，Base94 没有标准的填充机制。实现处理方式不同：

- **无填充**：某些实现简单地省略填充
- **长度前缀**：在输出中包含原始长度
- **终止符**：使用特定字符标记结束

### 前导零

整数转换方法可能丢失前导零字节。常见解决方案：

- 在输出前加上前导零计数
- 在转换前给整数添加偏置
- 使用保留字节边界的不同算法

### 大整数算术

Base94 编码需要任意精度算术。大多数实现使用：
- 内置 BigInt 类型（JavaScript、Python、Java）
- 自定义大整数库
- 避免完整大整数表示的流式算法

### 字符映射

从值 0-93 到字符的映射可以是：
- 直接：值 + 0x21（从 `!` 开始）
- 查找表：特定需求的自定义映射
- 标准：特定发布的字符集

## Base94 实践

### JavaScript 示例

```javascript
const CHARS = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~';

function base94Encode(buffer) {
  let num = BigInt('0x' + buffer.toString('hex'));
  if (num === 0n) return CHARS[0];
  
  let result = '';
  while (num > 0n) {
    result = CHARS[Number(num % 94n)] + result;
    num = num / 94n;
  }
  return result;
}
```

### Python 示例

```python
CHARS = '!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'

def base94_encode(data):
    num = int.from_bytes(data, 'big')
    if num == 0:
        return CHARS[0]
    result = []
    while num > 0:
        result.append(CHARS[num % 94])
        num //= 94
    return ''.join(reversed(result))
```

## 局限性

### 未标准化

Base94 没有像 Base64（RFC 4648）那样的官方 RFC。不同的实现可能：
- 使用不同的字符集
- 填充处理不同
- 字节边界处理不同

### 工具较少

与 Base64 相比，较少的库和工具支持 Base94：
- 没有内置浏览器/操作系统支持
- 较少的语言标准库
- 较少的社区文档

### URL 安全性

标准 Base94 字符集包含 URL 不安全字符（`<`、`>`、`"` 等）。对于 URL 上下文：
- 改用 URL 安全的 Base64
- URL 编码 Base94 输出
- 使用排除 URL 不安全字符的自定义字符集

## 何时使用 Base94

**使用 Base94 当**：
- 最大密度至关重要
- 您控制编码和解码两端
- 传输支持所有可打印 ASCII 字符
- 您需要比 Base64 提供的更大密度

**使用 Base64 当**：
- 需要与现有系统兼容
- 标准工具很重要
- 需要 URL 安全编码
- 您正在与期望 Base64 的 API 交互

**使用十六进制当**：
- 调试密码学值
- 使用 HSM 工具
- 人类可读性重要
- 需要最大兼容性

## 在线工具

使用 [Base94 编码器](/base94)：

- 将二进制数据编码为 Base94 格式
- 将 Base94 解码回二进制
- 与 Base64 和十六进制的输出大小比较
- 使用不同输入数据进行测试

所有处理都在浏览器中进行——您的数据永远不会离开您的设备。
