我正在尝试通过在Java中实现它来学习Inflate算法,以便我可以在汇编中为具有非常有限的指令集的CPU实现它。
在读取文字,距离和长度代码的数量后,我无法从文件中读取正确的代码长度。 我正在按照here所述的实现进行操作,其中提供了一个示例.gz文件gunzip.c.gz。在读取gzip头文件后,以下是第一个56位(如果我正确读取它),压缩数据块:
10111101 00011011 11111101 01101111 11011010 11001000 11110010
我将通过以下偏移来引用字节中的位:[76543210]
第一个字节10111101
包含偏移end of block
的{{1}},偏移0
包含确定块类型的两个位。
在这种情况下,这是最后一个块,它是一个动态的霍夫曼树。
要解释的以下位是文字(5位),距离(5位)和长度(4位)代码的数量。阅读内容如下:
21
在此之后,我遇到了麻烦。接下来的36位应该是12组3位,表示代码长度 从上面的字节,我看到(解释为little-endian):
10111101 -> 10111XXX -> 23 (literal)
00011011 -> XXX11011 -> 27 (distance)
00011011 11111101 -> 000XXXXX XXXXXXX1 -> 1000 -> 8 (length)
但我希望(如上面的链接所示)
110 111 111 011 011 010 011 011 100 100 101 100
3 7 7 6 6 2 6 6 1 1 5 1
我看不到从文件中获取这些值的任何方法。我必须误解应该如何读取这些位。给定一个具有5位值后跟3位值的字节101 011 011 110 110 110 110 110 110 001 001 001
5 6 6 3 3 3 3 3 3 4 4 4
,我会将其读作[CBA43210]
和01234
。
这篇文章的正确代码长度应该是错误的,或者更可能的是,我对它们应该如何解释是错误的?
答案 0 :(得分:1)
位本身被读取LSB到MSB,如图6所示:
<---- 87654321
(来自问题链接的文件)表示
[CBA43210]我会把它读作01234和ABC。
(来自问题本身)是正确的。
Little-endian表示首先存储或读取(此处,解释)最低有效位(此处为位)。
但是,01234
和ABC
本身属于小端,因此字节110 11000
将被解释为3 3
,而不是24 6
。
这意味着
中的五位,五位和四位10111101 00011011 ...
是
xxx11101 => 11101 => 29
101xxxxx
xxxxxx11 => 11 101 => 29
xx0110xx => 0110 => 6