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

zlib:解压缩数据时出现错误-3:无效距离太远

  •  3
  • knarf  · 技术社区  · 8 年前

    我试图编写代码来写/读MS-ZIP压缩的CAB文件。MS-ZIP使用在zlib中实现的相同的deflate算法。我已经将问题简化为这个只涉及zlib的简单脚本。

    • 解压缩功能不工作。当必须解压缩多个块时,它会失败。

    我无法获得与压缩代码匹配的解压缩代码。

    import sys, struct, zlib
    
    MAX_CHUNK_SIZE = 100
    
    def main():
        uncomp = (b'GQOLELNFJH@?AQE@LBA=?@N@<GJHE=EGE<FQOAM@?<IABT>EK'
                  b'<=QFRPBSRGFRENSJLDFGD=LSRHIAO?FB@NP?DGDS>NGT@CCFPS'
                  b'A@B=IGG<?JQBGBPLOPONU?IBBSNBK<QAFLGK@>H=CQ?BS><@UE'
                  b'QGAKHML@>?JOSEQRCTP>S<?N>DNM@??ARJ>QUJSHLQN<P<>D==')
    
        print("python", sys.version)
        print("zlib version", zlib.ZLIB_VERSION)
        print("zlib runtime version", zlib.ZLIB_RUNTIME_VERSION)
    
        chunks = compress(uncomp)
        decomp = decompress(chunks)
        assert(uncomp == decomp)
    
    
    def compress(data):
        start_off = 0
        data_size = len(data)
        remaining = data_size
        res = []
        zdict = b''
    
        while start_off < data_size:
            print("compress chunk %d"%len(res))
    
            chunk_size = min(MAX_CHUNK_SIZE, remaining)
            chunk = data[start_off:start_off+chunk_size]
            c = b''
    
            z = zlib.compressobj(wbits=-15, zdict=zdict)
            c += z.compress(chunk)
            c += z.flush(zlib.Z_FINISH)
    
            res.append(c)
    
            zdict = chunk
            start_off += chunk_size
            remaining -= chunk_size
    
        return res
    
    def decompress(chunks):
        zdict = b''
        res = []
    
        for i, c in enumerate(chunks):
            print("decompress chunk %d"%i)
            out = b''
    
            z = zlib.decompressobj(wbits=-15, zdict=zdict)
            out += z.decompress(c)
            out += z.flush()
            zdict = out
    
            res.append(out)
    
        return b''.join(res)
    
    
    if __name__ == '__main__':
        main()
    

    当我运行这个脚本时,我得到:

    python 3.4.5 (default, Jul 03 2016, 13:55:08) [GCC]
    zlib version 1.2.8
    zlib runtime version 1.2.8
    compress chunk 0
    compress chunk 1
    decompress chunk 0
    decompress chunk 1
    Traceback (most recent call last):
      File "bug.py", line 65, in <module>
        main()
      File "bug.py", line 16, in main
        decomp = decompress(chunks)
      File "bug.py", line 55, in decompress
        out += z.decompress(c)
    zlib.error: Error -3 while decompressing data: invalid distance too far back
    

    它在ideone.com上也失败了 http://ideone.com/baD3gg 它正在运行python 3.4.3+zlib 1.2.8

    1 回复  |  直到 8 年前
        1
  •  2
  •   knarf    8 年前

    似乎我遇到了CPython问题#27164。在我写这篇文章(2016-11-21)时,只有Branchs master和3.5版本提供了修复程序。

    https://bugs.python.org/issue27164

    推荐文章