或者更准确地说,当两个相同的字符串相互连接时,为什么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数据”。
答案 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?也许它太老了?