我对DEFLATE压缩的字节打包是否正确?

问题描述 投票:0回答:1

所以,我知道有很多库可以用来做DEFLATE压缩。 如果我在生产产品上工作,我会使用像zlib这样的东西。 但作为一种爱好,我自己实现它来试着弄明白。 所以经过几周的编码、重新编码和调整,我终于能够在合理的时间内产生一些我认为不错的输出。 然而,如果我试图将我的输出发布到在线工具中,我得到的错误不一定能帮助我找出输出的问题。 当我让我的程序生成一个实际的比特字符串,然后我用手将其解析出来,一切似乎都符合DEFLATE标准,我可以重建我的数据。 这使我相信我的编码是正确的,但我可能完全误解了打包字节时的不同位序。 以下是我的输出的Base64编码版本,然后是我的程序生成的8位字节列表。 如果有人能帮助我指出数据失败的地方,那将是非常感激的。

Defective program output (both Base64 and raw bytes):

Base64 Encoded Output:
ZYQhAQAADMKqQBWagELQXz/AzTQX+eAB

Byte List:
01100101
10000100
00100001
00000001
00000000
00000000
00001100
11000010
10101010
01000000
00010101
10011010
10000000
01000010
11010000
01011111
00111111
11000000
11001101
00110100
00010111
11111001
11100000
00000001

作为我对文档的理解的一个概述。 标准说,一个块的开始是用1位来声明它是否是最后一个块,然后用2bits来声明使用了什么类型的压缩,然后是5bits hlit,5bits hdist,4bits hclen,然后是hclen+4组3bits,每组3bits给出了用于输出字长代码以及距离代码的哈夫曼代码的代码长度。在这之后是由hlit+257+hdist+1码长组成的huffman编码字符串,最后是由块码末尾封顶的实际压缩数据的huffman编码字符串。 有趣的是,哈夫曼代码本身是以相反的顺序打包的......。 然而,我感到困惑的是,在一些长度码(码16、17、18)之后的 "额外位",以及在较高长度和距离码之后的 "额外位"。 这些额外的位是以与哈夫曼码相同的反向顺序打包,还是作为 "哈夫曼码以外的数据 "处理?

Looking at first byte in list (byte 0):

*01 = last block bit
*02 = 2bit compression type (10 = dynamic huffman)
*03 = msb of hlit (#of literal/length codes - 257)

 *03                 *02     *01
  v                   v       v
+-------------------------------+
| 0   1   1   0   0   1   0   1 |
+-------------------------------+
| Byte 0                        |



Looking at bytes 8 and 9 (starting with byte 0):

*01 = last bit of hclen + 4 sets of codelen code lengths
*02 = msb of huffman code "10" ("10" = codelen code 18 - repeat 0 11-138 times)
*03 = lsb of 7 "extra bits" for codelen code 18
*04 = msb of 7 "extra bits" for codelen code 18

                  *03     *02 *01                           *04
                   v       v   v                             v
+---------------------------------+---------------------------------+
|  1   0   1   0   1   0   1   0  |  0   1   0   0   0   0   0   0  |
+---------------------------------+---------------------------------+
| Byte 8                          | Byte 9                          |

下面是我的程序的一些附加输出,其中使用了实际的哈夫曼码。

--------------------------------------------------------------------------
Literal/Length Bit Codes:  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 Bit Codes:  Block: 0    hdist: (5 - 1) = 4
--------------------------------------------------------------------------
Code: 4         Count: 1        BitCode: 00                 Bit Length: 2                   

--------------------------------------------------------------------------
CodeLength Bit Codes:  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                   

--------------------------------------------------------------------------
--------------------------------------------------------------------------
c++ byte bit huffman-code deflate
1个回答
1
投票

额外的位子没有反过来。

你的问题是,长度为2的单距离码是不允许的。单个距离码的长度必须是1.来自RFC 1951:

如果只有一个距离码,则用一个比特而不是零比特来编码;在这种情况下,单码长度为1,还有一个未使用的码。

© www.soinside.com 2019 - 2024. All rights reserved.