0

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

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

10111101 00011011 11111101 01101111 11011010 11001000 11110010

我将通过以下偏移量来引用字节中的位:[76543210] 第一个字节10111101包含end of blockat 偏移量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]我会将其读取为01234and ABC

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

4

1 回答 1

1

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

<----
87654321

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

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

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

Little-endian 意味着首先存储或读取最低有效位(此处为位)或读取(此处为解释)。

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

这意味着五位、五位和四位

10111101 00011011 ...

xxx11101 => 11101  => 29
101xxxxx
xxxxxx11 => 11 101 => 29
xx0110xx => 0110   => 6
于 2012-12-03T06:46:15.313 回答