如何强制zlib解压缩超过X个字节?

时间:2013-03-29 00:00:49

标签: python zlib

我有一个由压缩内容和32字节标头组成的文件。标头包含时间戳,压缩大小和未压缩大小等信息。

文件本身大约是490mb,标题表示未压缩的大小接近2.7gb(显然不正确,因为它也认为压缩大小为752mb)。

我已经剥离了标头并生成了压缩的有效负载,并且可以使用zlib解压缩它。

问题是它只能解压缩19kb,远小于490mb(应该是最小值,但我预计大约700mb未压缩)。

我的代码如下:

import zlib

def consume (inputFile):
    content = inputFile.read()
    print "Attempting to process " + str(len(content)) + " bytes..."
    outfile = open('output.xml', 'w')
    inputFile = zlib.decompress(content)
    print "Attempting to write " + str(len(inputFile)) + " bytes..."
    outfile.write(inputFile)
    outfile.close()

infile = open('payload', 'rb') 

consume(infile)

infile.close()

运行时,程序输出:

  
    
      

尝试处理489987232字节...       试图写18602个字节...

    
  

我尝试使用zlib.decompressionobj(),但这会生成错误的标头警告。 zlib.decompress()工作正常并生成我期望的解压缩的XML ...只是太少了。

非常感谢任何指针或建议!

2 个答案:

答案 0 :(得分:3)

你的文件显然已损坏。

你将无法强制zlib忽略腐败 - 如果你这样做,你很可能得到700MB垃圾,或者随机垃圾量,或者......好吧,这取决于什么腐败就是在哪里。但你获得任何有用的机会都很渺茫。

zlib的块不是随机可访问的,或者是分隔的,甚至是字节对齐的;除非你能够处理前一个区块,否则很难判断你何时到达下一个区块。

另外,树木会逐块生长,所以即使你可以跳到下一个街区,你的树木也会出错,除非你非常非常幸运并且不需要破碎的树的一部分。更糟糕的是,任何块都可以重新启动树木(甚至可以切换压缩机);如果你错过了那个,你就会解压垃圾,即使你也很幸运。而且这不仅仅是“跳过这个字符串,因为我不认识它”,你甚至不知道如果你不认识字符串有多少位,所以你不能跳过它。这让我们回到第一点 - 你甚至不能跳过一个字符串,更不用说整个块了。

要更好地理解这一点,请参阅RFC 1951,其中介绍了zlib使用的格式。尝试手动处理一些简单的例子(第一个块中只有几个字符串,第二个块中有几个新字符串),看看以一种难以撤消的方式破坏它们是多么容易(除非你确切地知道它们是怎样的)被腐败了。它不是不可能(毕竟,破解加密的消息并非不可能),但我不相信它可以完全自动化,并且它不是你可能为了好玩而做的事情。

如果你有关键数据(并且不能只重新下载它,回滚到以前的版本,从备份恢复等),一些数据恢复服务声称能够恢复损坏的zlib / gz / zip文件。我猜这个费用是一条腿和一条腿,但它可能是正确数据的正确答案。

当然,我可能错了,因为这不是自动化的。那里有一堆zip恢复工具。据我所知,他们可以用破坏的zlib流做的就是跳过那个文件并恢复其他文件...但也许其中一些有一些技巧可以在某些情况下使用损坏的流。

答案 1 :(得分:0)

您需要检查zlib.error以查看它停止的原因。为什么要停止?