我正在编写一个需要解压缩由另一个应用程序压缩的数据的应用程序(这是我无法控制的 - 我无法对其源代码进行更改)。生产者应用程序使用zlib使用z_stream机制压缩数据。它经常使用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
,因此尚未设置deflate“final block”位。我假设这是因为流接口永远不知道输入数据的结束时间,所以永远不会设置该位?
最后,外部数据的最后四个字节是00 00 FF FF
,而在我的测试数据中,它是24 E9 04 55
。搜索我在这个页面上找到了
http://www.bolet.org/~pornin/deflate-flush.html
......这是同步或完全冲洗的签名。
当我尝试使用decompress()
函数解压缩我自己的数据时,一切都运行良好。但是,当我尝试解压缩外部数据时,decompress()
函数调用失败,返回代码为Z_DATA_ERROR
,表示数据已损坏。
我有几个问题:
我是否可以使用zlib“解压缩”功能解压缩已使用z_stream方法压缩的数据?
在上面的例子中,最后四个字节的意义是什么?鉴于外部压缩数据流和我自己的测试数据流长度相同,我的最后四个字节代表什么?
干杯
答案 0 :(得分:7)
感谢zlib的作者,我找到了答案。第三方应用程序正在生成未正确完成的zlib流:
78 9c f2 48 cd c9 c9 57 08 cf 2f ca 49 51 e4 e5 02 00 00 00 ff 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标题组成,单个 标记为最后一个块的块,以及a zlib预告片。预告片是 Adler-32校验和的未压缩 数据
所以我的解压缩失败 - 可能是因为CRC丢失,或者解压缩代码一直在寻找更多不存在的数据。
答案 1 :(得分:3)
解决方案在这里: http://technology.amis.nl/2010/03/13/utl_compress-gzip-and-zlib/
这是解压缩和压缩功能,以78 9C签名开始 压缩数据库blob(或流)。