【问题标题】:Why can't deflate (zlib) compress two identical strings concatenated together?为什么 deflate (zlib) 不能压缩两个相同的字符串连接在一起?
【发布时间】:2014-06-29 22:45:51
【问题描述】:

或者更准确地说,当两个相同的字符串相互连接时,为什么 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 不会膨胀输出。我收到错误“放气数据无效或不完整”

【问题讨论】:

    标签: compression gzip zlib deflate data-compression


    【解决方案1】:

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

    那么,DEFLATE 当然可以表示和压缩两个字符串的连接。为什么 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?也许它太旧了?

    【讨论】:

    • 谢谢。我一定是手工编码字符串时出错了。我检查了你的编码,它解压得很好。
    • 具有讽刺意味的是,我在介绍我自己的Internet Draft for an alternative token-based deflate algorithm 时提出了同样的论点:) ... RFC 1951 明确指出“deflate”格式与任何特定算法无关。引用,它说,“虽然本文档的目的是在不参考任何特定压缩算法的情况下定义'deflate'压缩数据格式,但该格式与 LZ77 产生的压缩格式有关...... [然而]为了合规,压缩机不需要遵循它。”
    猜你喜欢
    • 2016-01-06
    • 2012-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多