代码之家  ›  专栏  ›  技术社区  ›  Thomi

zlib解压失败

  •  10
  • Thomi  · 技术社区  · 15 年前

    我正在编写一个应用程序,它需要解压缩另一个应用程序压缩的数据(这超出了我的控制范围——我不能更改它的源代码)。生产者应用程序使用zlib使用z_流机制压缩数据。它经常使用z_full_flush(在我看来,可能太频繁了,但这是另一回事)。这个第三方应用程序还能够解压缩它自己的数据,所以我非常确信数据本身是正确的。

    在我的测试中,我使用这个第三方应用程序压缩以下简单的文本文件(十六进制):

    48 65 6c 6c 6f 20 57 6f 72 6c 64 21 0d 0a

    我从应用程序收到的压缩字节如下(同样是十六进制):

    78 9c f2 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 00 00 ff ff

    如果我尝试压缩相同的数据,我会得到非常相似的结果:

    78 9c f3 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 24 e9 04 55

    我可以看到两个不同之处:

    第一,第四个字节是 F2 而不是 F3 因此,放气“最终块”位尚未设置。我认为这是因为流接口永远不知道传入数据的结束时间,所以从不设置该位?

    最后,外部数据中的最后四个字节是 00 00 FF FF ,而在我的测试数据中 24 E9 04 55 . 我在这页上找到的四处搜索

    http://www.bolet.org/~pornin/deflate-flush.html

    …这是同步或完全刷新的签名。

    当我尝试使用 decompress() 功能,一切正常。但是,当我尝试解压缩外部数据时, 解压缩() 函数调用失败,返回代码为 Z_DATA_ERROR ,表示数据损坏。

    我有几个问题:

    1. 我应该能够使用zlib“uncompress”函数来解压缩用z_stream方法压缩的数据吗?

    2. 在上面的例子中,最后四个字节的意义是什么?考虑到外部压缩的数据流和我自己的测试数据流的长度相同,最后四个字节代表什么?

    干杯

    2 回复  |  直到 11 年前
        1
  •  7
  •   Thomi    15 年前

    感谢zlib的作者,我找到了答案。第三方应用程序正在生成未正确完成的zlib流:

    78 9C F2 48 CD C9 C9 57 08 CF 2F CA 49 51 E4 E5 02 00 00 00 00 FF家具

    这是部分zlib流, 由zlib头和 部分放气流。有两个 块,两者都不是最后一个 块。第二个块是空的 存储块,当 冲洗。zlib解码器 正确解码存在的内容,以及 之后继续查找数据 那些字节。

    78 9C F3 48 CD C9 C9 57 08 CF 2F CA 49 51 E4 E5 02 00 24 E9 04 55

    这是一个完整的zlib流, 包括一个zlib头,一个 标记为最后一个块的块,以及 Zlib拖车。拖车是 未压缩的ADLER-32校验和 数据。

    所以我的解压失败了——可能是因为CRC丢失了,或者解压代码一直在寻找不存在的更多数据。

        2
  •  3
  •   Ersin Kecis    11 年前

    解决方案如下: http://technology.amis.nl/2010/03/13/utl_compress-gzip-and-zlib/

    这是从789C签名开始的解压和压缩函数 压缩的数据库blob(或流)。