2012-12-03 33 views
0

我想通过在Java中实现它来学习膨胀算法,这样我就可以在一个非常有限的指令集的CPU中实现它。gzip:解释位解压

在阅读文字,距离和长度代码的数量后,我无法从文件中读取正确的代码长度。 我正在按照here所述的实施方式进行跟踪,他们提供了一个示例.gz文件gunzip.c.gz。在gzip的标头中读取后,以下是第一的前56位(和,如果我正确地读它,只)压缩数据块:

10111101 00011011 11111101 01101111 11011010 11001000 11110010 

我将把位在一个字节由跟随偏移量:[] 第一个字节10111101包含end of block,偏移量为0,偏移量21包含确定块类型的两位。
在这种情况下,这是最后一个块,它是一个动态霍夫曼树。

以下要解释的比特是文字(5比特),距离(5比特)和长度(4比特)码的数量。他们被读入如下:

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

在此之后,我遇到了麻烦。接下来的36位应该是12组3位,表示代码长度。
从上面的字节,我看到(可理解为小端):

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位值的字节,[CBA]我会将其读为ABC

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

回答

1

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

<---- 
87654321 

(从由问题链接的文档)表示

[CBA]我想将其读作和ABC。

(来自问题本身)是正确的。

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

然而,ABC本身是Little Endian的,所以字节110 11000将被解释为3 3,不24 6

这意味着

10111101 00011011 ... 

五,5年和4位

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

谢谢,做了一些测试。管理正确地解压大部分文件(我的程序遇到了一个我需要修复的错误)。但事实证明,我设法得到的原始表是正确的。该文章给出了错误的代码长度集。 – kieve