4

我有一个 Zip 存档,其中包含一个不会提取的大(重要)文件。我尝试过的所有 Zip 实用程序,包括那些声称可以恢复/修复损坏的 Zip 存档的实用程序都无法提取包含损坏的 zlib 压缩数据的文件。他们获取存档中的所有文件,但损坏的条目除外,后者会被跳过。

我用 C# 编写了一个小型实用程序应用程序,它解析 zip 存档、识别每个条目并解析出字段、解密数据部分,然后使用 DeflateStream(来自 zlib 的 .Net 实现)解压缩它们。一切正常,直到我到达损坏的入口。损坏的条目成功且完全解密(在 CTR 模式下使用 AES),但 DeflateStream 阅读器在抛出“坏状态(超额订阅动态位长度树)”之前只能通过大约 40MB 的解密数据。

是否有可能以某种方式“寻找”经过损坏的部分并继续解压缩数据?我想尽可能多地恢复文件,即使有一些漏洞。DeflateStream 没有实现 Seek 方法,如果我尝试创建一个新的 DeflateStream 并将底层 FileStream 定位到最后一个读取位置,它会抛出相同的“Bad State”异常。

4

1 回答 1

4

deflate 协议根据滑动窗口和前向流调整表格。

这不是一个块——每个部分都不是独立的数据单元,因此无法“跳过”坏块——​​而是用于计算/恢复表信息的流的移动“视图” . 话虽如此,我的简单结论是:实际上不可能:(

请参阅“放气”协议的解释

不那么脾气暴躁的数据恢复。


放气协议实际上有允许在使用的压缩器之间切换的“块”。但是,我怀疑它们是否可用于任何类型的恢复。它与实际上相当可恢复的 MPEG-4 相去甚远。

来自RFC 1951,它显示了它会有多复杂:

请注意,标头位不一定从字节边界开始,因为块不一定占用整数个字节。

并谈论能够跨越各个块的 LZ77 压缩器:(它是用于构建压缩信息的窗口内的整个流)。

请注意,重复的字符串引用可能引用前一个块中的字符串;即,后向距离可以跨越一个或多个块边界。

然而,有一丝希望:

当压缩器确定用新鲜树开始一个新块是有用的,或者当块大小填满压缩器的块缓冲区时,它会终止一个块。

我不会追逐一缕曙光:-/也许个别位寻找(并非所有位序列都是有效的块开始)然后运行算法直到它失败(可证明“无效”放气),然后退出并再次尝试直到这样起始位在某个“可接受”期间内没有产生无效状态。

这种方法需要对 deflate 协议引擎进行修改——这不是普通的 deflate 流处理器可以处理的任务。

于 2011-04-05T21:04:48.967 回答