【问题标题】:gzip: Interpreting bits for decompressiongzip:解压缩解释位
【发布时间】:2012-12-03 06:34:23
【问题描述】:

我正在尝试通过在 Java 中实现 Inflate 算法来学习它,这样我就可以在指令集非常有限的 CPU 的汇编中实现它。

在读取文字、距离和长度代码的数量后,我无法从文件中读取正确的代码长度。 我正在按照here 描述的实现进行操作,他们在其中提供了一个示例.gz 文件gunzip.c.gz。读入 gzip 标头后,以下是第一个(如果我没看错的话,只有)压缩数据块的前 56 位:

10111101 00011011 11111101 01101111 11011010 11001000 11110010

我将通过以下偏移量引用字节中的位:[76543210] 第一个字节10111101 包含end of block 偏移量0,偏移量21 包含确定块类型的两位。
在这种情况下,这是最后一个块,它是一个动态的 Huffman 树。

以下要解释的位是字面量(5 位)、距离(5 位)和长度(4 位)代码。它们的读法如下:

10111101 -> 10111XXX -> 23 (literal)
00011011 -> XXX11011 -> 27 (distance)
00011011 11111101 -> 000XXXXX XXXXXXX1 -> 1000 -> 8 (length)

在这之后,我遇到了麻烦。接下来的 36 位应该是 12 组 3 位,表示代码长度。
从上面的字节中,我看到(解释为 little-endian):

110 111 111 011 011 010 011 011 100 100 101 100
3   7   7   6   6   2   6   6   1   1   5   1

但我希望(如上面的链接所示)

101 011 011 110 110 110 110 110 110 001 001 001
5   6   6   3   3   3   3   3   3   4   4   4

我看不到任何从文件中获取这些值的方法。我一定是误解了应该如何读取这些位。给定一个 5 位值后跟一个 3 位值的字节,[CBA43210] 我会将其读取为01234ABC

文章在正确的代码长度应该是什么方面有错误,或者更有可能是我在如何解释它们方面有错误?

【问题讨论】:

    标签: java gzip inflate


    【解决方案1】:

    位本身被读取 LSB 到 MSB,如图 6 所示:

    <----
    87654321
    

    (来自问题链接的文档)表明

    [CBA43210] 我会把它读作 01234 和 ABC。

    (从问题本身)是正确的。

    Little-endian 表示首先存储或读取(此处为解释)最低有效数字(此处为位)。

    但是,01234ABC 本身是 little-endian,因此字节 110 11000 将被解释为 3 3,而不是 24 6

    这表示中的五位、五位和四位

    10111101 00011011 ...
    

    xxx11101 => 11101  => 29
    101xxxxx
    xxxxxx11 => 11 101 => 29
    xx0110xx => 0110   => 6
    

    【讨论】:

    • 谢谢,做了一些测试。设法正确解压缩了大部分文件(我的程序遇到了我需要修复的错误。)但事实证明我设法得到的原始表是正确的。文章给出了错误的代码长度设置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 2012-02-12
    • 2011-01-26
    • 1970-01-01
    相关资源
    最近更新 更多