2016-11-17 334 views
1

我正在尝试编写/读取MS-ZIP压缩CAB文件的代码。 MS-ZIP使用zlib中实现的相同放气算法。我已经简化了这个简单的脚本,只涉及zlib。zlib:解压缩数据时出错-3:无效距离太远

  • 我知道压缩功能是正确的,因为其他CAB提取工具可以读取文件产生这样。

  • 解压缩功能不起作用。当需要解压缩多个块时,它会失败。

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

import sys, struct, zlib 

MAX_CHUNK_SIZE = 100 

def main(): 
    uncomp = (b'[email protected][email protected][email protected]@<GJHE=EGE<[email protected]?<IABT>EK' 
       b'<[email protected]?DGDS>[email protected]' 
       b'[email protected]=IGG<?JQBGBPLOPONU?IBBSNBK<[email protected]>H=CQ?BS><@UE' 
       b'[email protected]>?JOSEQRCTP>S<?N>[email protected]??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这是运行蟒蛇3.4.3+的zlib 1.2.8

+0

我刚刚复制并粘贴你的代码,运行它,并得到'结果12/12确定'。 –

+1

(哇,嗨马克!!)我一直得到这些错误(测试5,6,7,8,9,10,11有时2,3)。运行zlib 1.2.8。 我试图转储数据并用C程序解压缩,与python脚本(也链接到1.2.8)相同的结果将用更多的代码编辑我的文章。 – knarf

+0

我已编辑帖子。 – knarf

回答

1

看来我是遇到CPython问题#27164。正如我在写这篇文章(2016年11月21日)时,修正版仅适用于分支机构主和3.5版。

https://bugs.python.org/issue27164

+0

的确,我的python版本是3.5.2。我得到:'python 3.5.2(v3.5.2:4def2a2901a5,Jun 26 2016,10:47:25) [GCC 4.2.1(Apple Inc. build 5666)(dot 3)] zlib 1.2.3版本 zlib运行时版本1.2.8 压缩数据块0 压缩数据块1 解压缩数据块0 解压缩数据块1' –