我在理解Deflate算法(RFC 1951)时遇到了麻烦。
TL; DR 如何解析Deflate压缩块4be4 0200
?
我创建了一个文件,其中包含一个字母和换行符a\n
,然后运行gzip a.txt
。结果文件a.txt.gz
:
1f8b 0808 fe8b eb55 0003 612e 7478 7400
4be4 0200
07a1 eadd 0200 0000
我知道第一行是包含附加信息的标题,最后一行是CRC32加上输入大小(RFC 1951)。这两个给我带来了麻烦。
但是如何解释压缩块本身(中间线)?
这是它的十六进制和二进制表示:
4be4 0200
0100 1011
1110 0100
0000 0010
0000 0000
据我了解,不知何故这些:
每个压缩数据块都以3个头位开头,包含以下数据:
- 第一位BFINAL
- 接下来的2位BTYPE
...实际上是在第一个字节的结束结束:0100 1 011 。 (我将跳过这个问题,为什么有人会称之为“标题”的东西实际上是其他东西的尾巴。)
RFC包含的内容据我所知应该是对此的解释:
- 数据元素按顺序打包成字节 增加字节内的位数,即开始 使用字节的最低位。
- 打包除霍夫曼代码以外的数据元素 从最低有效位数开始 元件。
- 霍夫曼代码从最开始包装 重要的代码。
换句话说,如果要将压缩数据打印出来 一个字节序列,从第一个字节开始 正确保证金并继续前往左,最多 - 像往常一样,左边每个字节的有效位,一个是 能够从右到左解析结果,具有固定宽度 正确的MSB到LSB顺序中的元素和中的霍夫曼代码 位反转顺序(即,使用代码的第一位) 相对LSB位置)。
但遗憾的是我不明白这个解释。
返回我的数据。好的,所以设置了BFINAL,而BTYPE是什么? 10或01?
如何解释该压缩块中的其余数据?
答案 0 :(得分:8)
首先让我们将压缩数据的十六进制表示看作一系列字节(而不是您问题中的一系列16位大端值):
4b e4 02 00
现在让我们将这些十六进制字节转换为二进制:
01001011 11100100 00000010 000000000
根据RFC,这些位被打包为“从字节的最低有效位开始”。字节的最低有效位是字节的最左位。所以第一个字节的第一位是这一个:
01001011 11100100 00000010 000000000
^
first bit
第二位是这一位:
01001011 11100100 00000010 000000000
^
second bit
第三位:
01001011 11100100 00000010 000000000
^
third bit
等等。一旦遍历了第一个字节中的所有位,就可以从第二个字节的最低有效位开始。所以第九位就是这个:
01001011 11100100 00000010 000000000
^
ninth bit
最后,最后一位,第三十二位,就是这一位:
01001011 11100100 00000010 000000000
^
last bit
BFINAL值是压缩数据中的第一位,因此包含在上面标记为“第一位”的单个位中。它的值为1,表示这是压缩数据中的最后一个块。
BTYPE值存储在数据的后两位中。这些是上面标记为“第二位”和“第三位”的位。唯一的问题是两者中哪一位是最低有效位,哪一位是最重要的位。根据RFC,“除了霍夫曼代码之外的数据元素被打包
从数据元素的最低有效位开始。“这意味着这两个位中的第一位,标记为”第二位“的位是最低有效位。这意味着BTYPE的值为01
in二进制。所以表示使用固定的霍夫曼码压缩块。
这就是容易完成的部分。解码压缩块的其余部分更加困难(并且使用更现实的示例,更加困难)。正确地解释这将如何使这个答案太久(并且你的问题太广泛)对于这个网站。我会给你一个提示,数据中接下来的三个元素是霍夫曼代码10010001('a'),00111010('\ n')和0000000(流结束)。其余6位未使用,不属于压缩数据。
请注意,要了解如何解压缩压缩数据,您必须了解Huffman codes是什么。您所遵循的RFC假设您这样做。您还应该知道LZ77 compression的工作原理,尽管文档或多或少地解释了您需要了解的内容。