为什么不能放气(zlib)压缩连接在一起的两个相同的字符串?

时间:2014-05-12 14:08:10

标签: compression gzip zlib deflate data-compression

或者更准确地说,当两个相同的字符串相互连接时,为什么zlib不能缩小整个第二个字符串?似乎当匹配的字符串在同一个字符串的前一个实例之后立即开始时,zlib将第一个字符作为字符串文字发出,然后向前一个字符串发出向后引用减去第一个字符。

例如,如果我使用zlib来缩小字符串 latelate ,则输出为5个字符串文字,后跟后引用...

l a t e l <len=3, dist=4>

或霍夫曼编码...

0000000 cb 49 2c 49 cd 01 62 00
0000010

我通过使用“原始”deflate流(即windowBits = -15)和固定霍夫曼编码(即压缩策略为Z_FIXED)来简化输出。

为什么zlib在使用“ate”的后引用之前必须发出第二个文字字符'l'?

换句话说,为什么不输出......?

l a t e <len=4, dist=4>

我尝试使用我自己的deflate实现强制第二个版本,但zlib不会对输出进行膨胀。我收到错误“无效或不完整的deflate数据”

1 个答案:

答案 0 :(得分:2)

让我们分开DEFLATE,作为zlib的https://www.ietf.org/rfc/rfc1951.txt中描述的压缩比特流格式,它是对这种比特流进行编码和解码的算法的实现。

然后,DEFLATE肯定可以表示和压缩2个字符串的连接。为什么zlib不这样做?好吧,因为匹配搜索LZ77压缩本质上是启发式任务,所以有些选择不会被探索,甚至是那些对人类来说显而易见的选择。

使用基于哈希的普通LZ77编码器,很容易找到双字符串的情况:

L6c # l
L61 # a
L74 # t
L65 # e
C-4,4

这个序列可以用静态zlib编码编码而没有问题,结果是:

CB 49 2C 49 05 61 00

zlib也可以毫无问题地解码这个比特流。你可以尝试使用Python:

import zlib
import binascii
zlib.decompress(binascii.unhexlify("CB492C49056100"), -15)

那么,您使用的是什么版本的zlib?也许它太老了?