【问题标题】:how to zlib inflate a gzip/deflate archive如何 zlib 对 gzip/deflate 存档进行膨胀
【发布时间】:2021-07-24 00:30:27
【问题描述】:

我有一个使用 gzip 1.5 编码的存档。我无法使用 C zlib 库对其进行解码。 zlib inflate() return EC -3 stream.msg = "未知压缩方式"。

$ gzip --list --verbose vmlinux.z
method  crc     date  time           compressed        uncompressed  ratio uncompressed_name
defla 12169518 Apr 29 13:00             4261643             9199404  53.7% vmlinux

文件的前 32 个字节是:

00000000  1f 8b 08 08 29 f4 8a 60  00 03 76 6d 6c 69 6e 75  |....)..`..vmlinu|
00000010  78 00 ec 9a 7f 54 1c 55  96 c7 6f 75 37 d0 fc 70  |x....T.U..ou7..p|

我看到前 18 个字节是 RFC-1952 gzip 标头。 在 NULL 之后,我希望下一个字节是 RFC-1951 deflate 或 RFC-1950 zlib(我不确定是哪个)

所以,我通过 zlib inflate() 一个 z_stream:next_in 指向字节 @0x12。

如果这是 deflate 编码,那么我希望下一个字节 @0x12 是 0aabbbbb(BFINAL=0 和 BTYPE=一些压缩)

如果这是 zlib 编码,我希望下一个字节 @0x12 采用 0aaa1000 bbbccccc 的形式

相反,我看到 @0x12 EC = 1110 1100 这两个都不适合。

对于我的代码,我采用了 uncompress() 代码,并使用适合我的环境的分配器和几个不同的窗口位实验(包括 15+16-MAX_WBITSMAX_WBITS)对其进行了轻微修改。

int ZEXPORT unzip (dest, destLen, source, sourceLen)
    Bytef *dest;
    uLongf *destLen;
    const Bytef *source;
    uLong sourceLen;
{
    z_stream stream;
    int err;

    stream.next_in = (Bytef*)source;
    stream.avail_in = (uInt)sourceLen;
    /* Check for source > 64K on 16-bit machine: */
    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;

    stream.next_out = dest;
    stream.avail_out = (uInt)*destLen;
    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;

    stream.zalloc = (alloc_func)my_alloc;
    stream.zfree = (free_func)my_free;

    /*err = inflateInit(&stream);*/
    err = inflateInit2(&stream, 15 + 16);
    if (err != Z_OK) return err;

    err = inflate(&stream, Z_FINISH);
    if (err != Z_STREAM_END) {
        inflateEnd(&stream);
        return err == Z_OK ? Z_BUF_ERROR : err;
    }
    *destLen = stream.total_out;

    err = inflateEnd(&stream);
    return err;
}

如何更正我对该文件的解码?

【问题讨论】:

  • 您在问题中完全没有提供任何代码。您是否使用了inflateInit2() 并请求 gzip 解码?
  • 嗨,马克,感谢您的收看。我已经添加了代码。我希望这会有所帮助。如果您发现明显的错误,我会喜欢您的见解。我也对如何理解 gzip 标头之后的编码感兴趣。这些字节是什么意思?

标签: gzip zlib deflate


【解决方案1】:

假设my_allocmy_free 做了他们需要做的事情,那应该可以正常工作。你应该验证你实际上给unzip()你认为你给它的数据。你给它的数据需要以1f 8b开头。

(旁注:“unzip”是一个糟糕的函数名称。它不会解压缩,因为 zip 是一种与 gzip 或 zlib 完全不同的格式。“gunzip”或“ungzip”是合适的。)

您正在以错误的顺序手动读取 deflate 流中的位。最低有效位在前。 ec的低三位为100,表示非最后一个动态块。 0 表示非最后一个,然后10 表示动态。

您可以使用infgen 来反汇编一个deflate 流。它提供的 14 个字节的输出是动态块的初始部分:

dynamic
count 286 27 16
code 0 5
code 2 7
code 3 7
code 4 5
code 5 5
code 6 4
code 7 4
code 8 2
code 9 3
code 10 2
code 11 4
code 12 4
code 16 7
code 17 7
lens 4 6 7 7 7 8 8 8 7 8
repeat 3
lens 10

【讨论】:

  • 谢谢,感谢您的帮助。几天后我会重新使用设备。那我试试看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-10
相关资源
最近更新 更多