【问题标题】:Zlib inflate works differently to C?Zlib inflate 与 C 的工作方式不同?
【发布时间】:2020-07-22 23:05:04
【问题描述】:

我试图在 java 中对一个字节数组进行 zlib 膨胀,但是当我膨胀它时我没有得到 Z_STREAM_END 返回。 我的代码与我查看的一些 C 代码完全相同,它们使用相同的数据、滑动窗口和其他参数(我认为?)。 我正在使用 JZlib。这是我的 Java 代码(dgboff 只是这个 zlib 字节数组在文件中的偏移量):

private byte[] z_decompress(byte[] in,int insize,byte[] out,int outsize) {
    ZStream zlib = new ZStream();
    zlib.inflateInit(15);//32k window (2^15)
    zlib.next_in=in;
    zlib.avail_in=insize;
    zlib.next_out=out;
    zlib.avail_out=outsize;
    if(zlib.inflate(JZlib.Z_FINISH)!=JZlib.Z_STREAM_END) {
        System.out.println("Incomplete zlib input at offset "+dgboff+". Compressed size: "+insize+", uncompressed size: "+outsize);
        System.exit(1);
    }
    zlib.inflateEnd();
    return zlib.next_out;
}

这是 C 代码,它可以工作(忽略杂乱的间距):

 z = calloc(1, sizeof(z_stream)); 
    if(!z) std_err(); 
    z->zalloc = (alloc_func)0; 
    z->zfree  = (free_func)0; 
    z->opaque = (voidpf)0; 
if(inflateInit2(z, 15)) { 
        printf("\nError: initialization error\n"); 
        exit(1); 
 } 
inflateReset(z);

z->next_in   = in;
z->avail_in  = insz;
z->next_out  = out;
z->avail_out = outsz;
if(inflate(z, Z_FINISH) != Z_STREAM_END) {
    printf("\nError: the compressed zlib/deflate input at offset 0x%08x (%d -> %d) is wrong or incomplete\n", (int)g_dbg_offset, (int)insz, (int)outsz);
    exit(1);
}
//gets to here in C

如果有什么我遗漏的请告诉我!

我正在测试的数据的 zlib 标头是 0x649d。

【问题讨论】:

  • 它返回了什么
  • 另外,看起来这个ZStream 类被标记为已弃用,您可能应该改用InflaterInputStream
  • 您确定两个实例都获得完全相同的字节序列吗? 0x649d 不是 zlib 标头。
  • C一返回输出字节的长度,字节在一个指针处。
  • 他们肯定会这样做,我将标题更改为 0x329d 以查看它是否会更改任何内容(使用十六进制编辑器)并且 C 版本说有错误。那么它可能会对字节做些什么呢?我要去看看代码,也许字节数组在那里发生了变化。我正在查看的 C 代码来自 ttarchext,一个游戏存档提取器。

标签: java c zlib jzlib


【解决方案1】:

您的数据不是 zlib 流,也没有 zlib 标头。这是一个原始的放气流。如图所示,您的两个代码示例都无法正常工作。您的“这里是 C 代码,可以工作”一定是其他 C 代码。

要解压原始膨胀数据,您需要使用-15(而不是15)作为inflateInit2() 的第二个参数。

顺便说一下,您提供链接的 deflate 压缩数据不完整。就它而言是正确的,但它不会终止。

【讨论】:

  • 实际的C代码不是那个,我把我认为没有影响的代码拿出来,这里是完整的C方法:pastebin.com/fHuF1LS0
  • 我已经修复了代码,现在可以使用了。还有一个问题,当我尝试使用 -15 时,我得到 -5(zstream buf 错误)。为什么会发生这种情况?
  • 可能是因为您告诉 inflate 您使用 Z_FINISH 提供了完整的 deflate 流,但 inflate 发现您对它撒了谎,并且您的 deflate 流没有终止。
  • 我能做些什么来解决这个问题?
  • 查找并提供完整的放气流。您不必使用Z_FINISH,您可以使用多个inflate() 调用来处理所有数据,但您最终需要提供完整的流才能获得Z_STREAM_END
猜你喜欢
  • 2013-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多