我有一个Zip档案,其中包含一个无法提取的大型(重要)文件。我尝试过的所有Zip实用程序,包括声称恢复/修复损坏的Zip存档的Zip实用程序都无法提取包含损坏的zlib压缩数据的文件。他们获取存档中除之外的所有文件,以获取被删除的条目。
我在C#中编写了一个小实用程序应用程序来解析zip存档,识别每个条目并解析字段,解密数据部分,然后使用DeflateStream(来自zlib的.Net实现)对它们进行解压缩。一切正常,直到我遇到损坏的入口。损坏的条目成功完全解密(在CTR模式下使用AES),但DeflateStream阅读器只能在解密数据中通过大约40MB,然后抛出“错误状态(超额订阅动态比特长度树)”。
是否有可能以某种方式'寻找'经过损坏的部分并继续解压缩数据?我想恢复尽可能多的文件,即使有一些漏洞。 DeflateStream没有实现Seek方法,如果我尝试创建一个新的DeflateStream,其底层FileStream位于最后一个读取位置,它会抛出相同的“Bad State”异常。
答案 0 :(得分:3)
deflate协议根据滑动窗口和前向流来调整表格。
这不是一个块 - 每个部分都不是独立的数据单元,因此无法“跳过”坏块 - 而是用于计算/恢复的流的“移动”视图表信息。话虽如此,我的简单结论是:不现实:(
请参阅An Explanation of the "Deflate" Protocol。
低于脾气暴躁的数据恢复。
deflate协议实际上有'块',允许在使用的压缩器之间切换。但是,我怀疑它们可以用于任何类型的恢复。它与MPEG-4相差甚远,而MPEG-4实际上是可以恢复的。
来自RFC 1951,它显示了它的复杂程度:
请注意,标头位不一定从字节边界开始,因为块不一定占用整数个字节。
谈论能够跨越各个块的LZ77压缩器:(它是窗口中用于构建压缩信息的整个流)。
请注意,重复的字符串引用可能引用前一个块中的字符串;即,后向距离可以越过一个或多个块边界。
然而,有一丝希望:
当压缩器确定启动带有新树的新块时,或者当块大小填满压缩器的块缓冲区时,压缩器会终止块。
不是我会追逐的光线: - /也许是个别位搜索(并非所有位序列都是有效的块启动)然后运行算法直到它失败(可证明“无效”放气),然后退出并尝试再次,直到这样的起始位在某个“可接受”的时间段内没有产生无效状态。
此方法需要修改deflate协议引擎 - 这不是正常的deflate流处理器可以处理的任务。