我正在研究Gzip的内部工作方式,我知道它使用了Huffman Coding和LZ77的组合。
我也意识到Gzip文件被分成块,每个块都有一个为它构建的字典。然后频繁出现的类似数据被指向字典中位置的指针所取代。
所以短语“赛马其他马匹”会用指针代替 horse 这个词。
但是,如果我有一个32位整数数组,但它只能存储多达24位的数字呢?为了论证,可以说这些24位数字非常随机且很难压缩,很难找到重复。
这会使每个整数的前8位容易压缩0的字符串,但每个字符串都需要一个指针,每个指针仍占用一些数据量。即使是1位指针(我知道它比实际可能的小)也会占据原始空间的12.5%。
当数组可以很容易地简化为“24位”数组并具有基本模式识别时,这似乎有点多余。
所以我的问题是:
Gzip是否包含任何比字典指针更好地压缩文件的机制?
Gzip如何压缩少量重复数据,然后是少量难以压缩的数据?
答案 0 :(得分:0)
每个deflate块都没有“为它构建的字典”。为每个deflate块构建的是一组用于文字/长度符号和距离符号的霍夫曼代码。
您引用的字典只是紧接在当前正在压缩的字节之前的32K字节的未压缩输入。而已。每个长度/距离对可以指最后32K中3到258个字节的字符串。这与deflate块无关,这种引用通常会返回一个或多个块。
Deflate不会很好地压缩三个随机字节,零字节,三个随机字节,零字节的序列......没有有用的重复字符串,其中deflate只能将Huffman编码为文字,零更频繁。它将零编码为两位,因为它们出现的时间略多于25%,而其余的字面值至少为8.25位。对于这样的数据,平均每字节约6.7位或压缩比为0.85。实际上gzip对这些数据的贡献大约为0.86。
如果你想压缩那个序列,只需删除零字节!然后就完成了,没有进一步的压缩,比例为0.75。