如何 gzip 压缩并 Base64 编码
- 在输入框中输入或粘贴文本,或拖入文件。实时 默认开启,输出会随输入更新。
- 格式 保持为 gzip。同一列表中还有 zlib、原始 deflate,以及浏览器支持时的 Brotli。
- 如果字符串要放进 URL 或文件名,勾选 URL 安全(- _);用于电子邮件或 PEM 式的行长度时,勾选 每 76 字符换行。
- 按 复制输出,按 下载 把 Base64 保存为
.txt文件,或按 下载压缩文件 保存二进制的.gz。
信息栏显示输入大小、压缩后大小、Base64 大小和压缩率,状态提示会说明结果比同一输入的纯 Base64 短了或长了多少。
什么时候值得先压缩
Base64 总会让数据增大三分之一。对于有重复内容的数据,gzip 能把这部分赚回来,甚至更多。
| 输入 | 纯 Base64 | Gzip + Base64 |
|---|---|---|
Hello, world!(13 字节) | 20 个字符 | 44 个字符 |
| 包含 100 条商品记录、9,281 字节的 JSON 数组 | 12,376 个字符 | 1,096 个字符 |
| 一张 JPEG 照片 | 约为文件的 4/3 | 比纯 Base64 略长 |
这些数字是用 gzip -6 得到的。浏览器的压缩器可能相差几个字节,信息栏会显示你的输入的确切数字。经验法则:100 字节左右以下的输入,以及任何已压缩的内容,直接用纯 Base64 更好。
gzip + Base64 字符串的使用场景
- Cloud-init 和虚拟机 user data:cloud-init 能识别 gzip 压缩的 user data,有助于不超出云元数据服务的大小限制。
- AWS CloudWatch Logs 订阅 以 gzip 数据的 Base64 形式,把日志批次放在
awslogs.data中投递给 Lambda。 - Helm 3 把每个 release 存为 gzip 压缩 JSON 的 Base64,放在 Kubernetes Secret 中。
- 环境变量和 JSON 字段:需要容纳配置文件或大段文本时。
- 查询字符串和深层链接:携带状态对象时。这里请使用 URL 安全输出。
除了 H4sI 前缀,Base64 中没有任何标记能告诉接收方数据是 gzip。请在字段名或 API 文档中写明;如果走 HTTP,可以改为发送二进制请求体并带上 Content-Encoding: gzip,而不用 Base64。
在代码中使用 gzip + Base64
import base64, gzip
data = open("products.json", "rb").read()
packed = base64.b64encode(gzip.compress(data, mtime=0)).decode()
// Node.js
const zlib = require("zlib");
const packed = zlib.gzipSync(Buffer.from(text)).toString("base64");
在浏览器中,new CompressionStream("gzip") 负责压缩,本页用的就是它。更多示例见 Python 和 Node.js 页面。
常见问题
- 接收方得到一堆乱码:它解码了 Base64,但没有解压。检查是否以
H4sI开头,并用 gzip Base64 解码器 解压。 - 对方报 “incorrect header check”:接收方需要的是 zlib,而不是 gzip。把 格式 切换为 zlib(deflate);zlib 页面 解释了哪些库需要哪种格式。
- Brotli 是灰色的:浏览器内置的压缩 API 不提供 Brotli,页面会在选项下方说明这一点。
- 输出与其他工具不同:gzip 头部带有时间戳和操作系统字节,各压缩器选择的压缩级别也不同。不同的字节可以解压出相同的内容。
常见问题
先 gzip 再 Base64,字符串会变短吗?
对于几百字节以上的文本、JSON、XML 和日志,通常会短很多。对于短字符串和已经压缩过的数据(JPEG、PNG、ZIP、MP4),结果反而更长,因为 gzip 会加上 18 字节的头部和尾部。
为什么 gzip 的 Base64 字符串总以 H4sI 开头?
gzip 数据以字节 1F 8B 08 开头,这三个字节的 Base64 就是 H4sI。后面的字符取决于标志位和时间戳:H4sIAAAAAAAA 表示没有文件名,也没有修改时间。
怎样在终端中 gzip 压缩并 Base64 编码?
Linux 上:gzip -nc file.json | base64 -w0。macOS 的 base64 没有 -w,请用 gzip -nc file.json | base64 | tr -d '\n'。-n 会省略文件名和时间,这样同样的输入总是得到同样的输出。