DEFLATE 和 Gzip 格式

最后更新: 2023-09-27 03:10:18 +0800 +0800
原文以英文撰写。您正在阅读AI翻译版本。

DEFLATE 是 RFC 1951 定义的位流格式。它将 LZ77 滑动窗口与霍夫曼编码 结合起来。“zlib”和“gzip”通常指包含 DEFLATE 的文件,但它们分别是 围绕原始位流的不同封装格式。

块边界和 BTYPE #

DEFLATE 流由一系列块组成。每个块都从当前位位置开始,依次包含 BFINAL(1 位)和 BTYPE(2 位):

BTYPE含义
00未进行霍夫曼编码的存储字节
01使用固定霍夫曼编码压缩
10使用动态霍夫曼编码压缩
11保留值,无效

只有最后一个块的 BFINAL 为 1。当字面量/长度流发出块结束符 (EOB)符号 256 时,压缩块结束。下一个块头会紧接在下一个位处出现; 压缩块不会填充到字节边界。存储块是例外:读取其头部后,解码器会丢弃 当前字节中的剩余位,读取小端序的 LEN 和 NLEN(LEN 的按位取反), 然后准确复制 LEN 个字节。LEN 为 16 位,因此单个存储块最多容纳 65,535 个字节。

LZ77 符号和霍夫曼编码 #

压缩数据字母表包含字面量字节 0–255、EOB 256,以及长度符号 257–285。 长度符号选择一个基础长度和额外位数。随后出现的距离符号选择一个基础 距离和额外位数。由此得到的二元组会从已经生成的输出中复制字节,向后 最多 32 KiB,长度最多 258 个字节;复制区域重叠是有效的。

固定块使用 RFC 1951 规定的编码长度。动态块包含 HLIT(5 位)、 HDIST(5 位)和 HCLEN(4 位),随后按照规定的排列传输编码长度 字母表。该字母表描述字面量/长度编码和距离编码的编码长度,其中包括用于 表示连续零或重复长度的重复符号。通过规范重建,可以将这些长度转换为 实际编码。

DEFLATE 在每个字节内从最低有效位向最高有效位打包数据元素。数值型 额外位字段采用最低有效位优先顺序。霍夫曼编码以规范值分配,但会按照 该格式规定的位反转约定发出。解析器必须维护位游标,而不能将每个字段 都作为字节对齐的整数读取。

zlib 和 gzip 封装格式 #

原始 DEFLATE 没有头部或尾部。zlib 封装格式(RFC 1950)以 CMF 和 FLG 开始,其中 FCHECK 确保 16 位头部可被 31 整除。如果设置了 FDICT,其后会跟随一个四字节的 Adler-32 字典标识符。流以未压缩数据 的大端序 Adler-32 结束。

gzip 封装格式(RFC 1952)是一系列成员。每个成员都包含魔数节 1f 8b、 压缩方法 8、标志、修改时间、额外标志和操作系统字段。标志可以添加 额外字段、原始文件名、注释和头部 CRC。尾部存储未压缩成员的小端序 CRC-32,以及 ISIZE,即其大小对 2³² 取模的结果。元数据不能替代 对尾部的验证。

协议文档必须明确表示形式。HTTP Content-Encoding: gzip 携带 gzip 格式,而使用 method 8 的 ZIP 条目通常携带原始 DEFLATE 流。不能仅因为 某个负载被描述为“compressed”,就安全地选择 zlib 解码器。

参考资料 #

评论

在 GitHub 上阅读或评论(发表评论需要登录)