是否有可能恢复损坏的Zlib数据超出损坏的部分

本文关键字:损坏 Zlib 有可能 恢复 是否 数据 | 更新日期: 2023-09-27 17:48:58

我有一个无法解压的大(重要)文件的Zip归档文件。我尝试过的所有Zip实用程序,包括那些声称可以恢复/修复损坏的Zip存档的工具,都无法提取包含损坏的zlib压缩数据的文件。它们获得存档中的所有文件,除了中被损坏的条目,该条目被跳过。

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

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

是否有可能恢复损坏的Zlib数据超出损坏的部分

deflate协议基于滑动窗口和前向流来调整表。

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

参见"Deflate"协议说明

小于暴躁的数据恢复。


deflate协议实际上有"块",允许在使用的压缩器之间切换。然而,我怀疑它们是否可用于任何形式的恢复。这与MPEG-4相差甚远,后者实际上是相当可恢复的。

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

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

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

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

然而,还是有一线希望的:

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

我不会追逐的光线:-/也许单个寻位(不是所有的位序列都是有效的块开始),然后运行算法直到它失败(可证明的"无效"deflate),然后后退并再次尝试,直到这样的起始位在一些"可接受"的时间内没有产生无效状态。

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