【问题标题】:Inflate decompression operation success without processing complete compressed dataInflate 解压操作成功,没有处理完整的压缩数据
【发布时间】:2023-05-04 03:48:01
【问题描述】:

我正在使用 Software Inflate 方法(原始 deflate 方法而不是 GZIP/ZLIB 变体)进行解压缩操作。

奇怪的是,我注意到以下观察结果

1.) 当我传入一个压缩缓冲区(avail_in 和 next_in 字段)作为源数据和一个目标缓冲区(avail_out 和 next_out)作为解压缩输出时,膨胀解压操作成功,Z_STREAM_END 为正状态。我还将它与原始未压缩数据及其匹配项进行了比较。

2.) 但是,当我将压缩数据拆分为两个缓冲区时,1 个缓冲区的压缩数据减去一个字节(压缩数据大小 -1),第二个缓冲区的大小为 1 字节,单个目标缓冲区的大小与原始缓冲区相同未压缩长度,膨胀解压操作成功,Z_OK 正状态填充了我的完整目标缓冲区(avail_out = 0 和 total_out = 原始未压缩大小)。我还将它与原始未压缩数据及其匹配项进行了比较。

我对为什么 inflate() 操作成功生成所有原始数据而不处理第二个源缓冲区感到非常困惑。?这是膨胀操作的预期行为吗?

3.) 我还尝试了上述 2 种方法,将源数据拆分为 2 个缓冲区,其中最后一个缓冲区的长度为 2 个字节,1 个源缓冲区大小是压缩数据 -2 和单个目标缓冲区。看到与2.

【问题讨论】:

    标签: c compression deflate inflate


    【解决方案1】:

    这种行为是意料之中的。

    膨胀的数据是可变位长代码流,连接在一起形成字节流。各个代码单元不是字节对齐的,压缩流通常不会在字节边界上结束。所以压缩流的最后一个字节很可能有几个未使用的位。

    压缩流不存储其长度。相反,其中一个代码单元用作流结束指示符。代码单元本身本质上是霍夫曼代码,所以最常见的是最短的。流结束指示符在流中只出现一次,因此其代码很可能超过 8 位。

    所以保证压缩流的最后一个字节只包含流结束指示符,而且流结束指示符很可能也占据了整个倒数第二个字节,还有一个倒数第三个字节的几位。 (我很确定代码长度限制在 16 位,但我没有查看参考资料。)

    每个代码单元对应原始消息中的一个或多个字节,这些字节可以在不参考下一个代码单元的情况下重新生成。如果你解压到流结束之前的代码单元,你已经解压了整个文件;流结束指示器告诉您的唯一一件事就是您已经完成了。

    【讨论】:

    • 非常感谢。所以你的意思是放气(充气)减压算法没有固定大小的蒸汽标记末端。 ?
    • @user3555115:从技术上讲,存在三种数据块:未压缩的、使用固定霍夫曼码压缩的、使用动态计算的霍夫南码压缩的。大多数块属于第三种类型。在这种情况下,代码项的长度会因块而异。
    最近更新 更多