DEFLATE压缩字节打包正确性排查及比特顺序疑问
问题背景
我了解有许多可实现DEFLATE压缩的库,生产环境会使用zlib,但作为个人爱好,我自行实现DEFLATE以深入理解其原理。经过数周编码调试,程序已能生成预期输出,但将输出提交至在线工具时会报错,且错误信息无法定位问题。手动解析程序生成的比特流时,所有内容均符合DEFLATE标准,可重建数据,因此我认为编码逻辑正确,但可能完全误解了字节打包时的比特顺序差异。恳请协助定位问题所在。
有问题的程序输出
Base64编码输出
ZYQhAQAADMKqQBWagELQXz/AzTQX+eAB
原始8位字节列表(二进制)
01100101 10000100 00100001 00000001 00000000 00000000 00001100 11000010 10101010 01000000 00010101 10011010 10000000 00100010 11010000 01011111 00111111 11000000 11001101 00110100 00010111 11111001 11100000 00000001
对DEFLATE文档的理解疑问
我对文档的理解概述:DEFLATE标准规定,一个块以1位标识是否为最后一个块开头,随后2位表示压缩类型,接着是5位hlit、5位hdist、4位hclen,之后是hclen+4组各3位的比特,用于给出编码literal/length码及distance码的Huffman码的码长。之后是hlit+257+hdist+1个码长的Huffman编码串,最后是实际压缩数据的Huffman编码串,以块结束码收尾。
有趣的是,Huffman码本身是反向打包的……但我困惑的是,部分长度码(16、17、18)及高位长度码、distance码后的“额外比特”,是否与Huffman码采用相同的反向顺序打包,还是被视为“Huffman码以外的数据”?
字节细节分析
第0字节解析
+-------------------------------+ | 0 1 1 0 0 1 0 1 | +-------------------------------+ | Byte 0 |
- 01(指向左数第一个位:0):最后一个块标识位
- 02(指向左数第二、三个位:1、1):2位压缩类型(10 = 动态Huffman)
- 03(指向剩余位):hlit的最高有效位(literal/length码数量 - 257 = 12)
第8、9字节解析
+---------------------------------+---------------------------------+ | 1 0 1 0 1 0 1 0 | 0 1 0 0 0 0 0 0 | +---------------------------------+---------------------------------+ | Byte 8 | Byte 9 |
- 01(指向Byte8最右边的位:0):hclen+4组码长码的最后一位
- 02(指向Byte8左数第二、三个位:0、1):Huffman码"10"的最高有效位("10" = 码长码18 - 重复0 11-138次)
- 03(指向Byte8的部分位):码长码18的7个“额外比特”的最低有效位
- 04(指向Byte9的部分位):码长码18的7个“额外比特”的最高有效位
实际使用的Huffman码详情
Literal/Length比特码
-------------------------------------------------------------------------- Block: 0 hlit: (269 - 257) = 12 -------------------------------------------------------------------------- Code: 32 Count: 1 BitCode: 000 Bit Length: 3 Code: 33 Count: 1 BitCode: 001 Bit Length: 3 Code: 66 Count: 1 BitCode: 010 Bit Length: 3 Code: 97 Count: 1 BitCode: 011 Bit Length: 3 Code: 98 Count: 1 BitCode: 100 Bit Length: 3 Code: 104 Count: 1 BitCode: 101 Bit Length: 3 Code: 108 Count: 1 BitCode: 110 Bit Length: 3 Code: 256 Count: 1 BitCode: 1110 Bit Length: 4 Code: 268 Count: 1 BitCode: 1111 Bit Length: 4
Distance比特码
-------------------------------------------------------------------------- Block: 0 hdist: (5 - 1) = 4 -------------------------------------------------------------------------- Code: 4 Count: 1 BitCode: 00 Bit Length: 2
CodeLength比特码
-------------------------------------------------------------------------- Block: 0 hclen: (16 - 4) = 12 -------------------------------------------------------------------------- Code: 2 Count: 1 BitCode: 110 Bit Length: 3 Code: 3 Count: 7 BitCode: 00 Bit Length: 2 Code: 4 Count: 2 BitCode: 111 Bit Length: 3 Code: 17 Count: 4 BitCode: 01 Bit Length: 2 Code: 18 Count: 5 BitCode: 10 Bit Length: 2
内容的提问来源于stack exchange,提问作者DynasticSponge




