1

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

例如,如果我使用 zlib 对字符串latelate进行压缩,则输出是 5 个字符串文字,后跟一个反向引用......

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

或霍夫曼编码...

0000000 cb 49 2c 49 cd 01 62 00
0000010

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

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

也就是说,为什么不能输出……?

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

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

4

1 回答 1

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?也许它太旧了?

于 2014-08-21T16:39:54.033 回答