4

抽出できない大きな (重要な) ファイルを含む Zip アーカイブがあります。壊れた Zip アーカイブを回復/修正すると主張するものを含め、私が試したすべての Zip ユーティリティは、破損した zlib 圧縮データを含むファイルを抽出できません。スキップされる破損したエントリを除いて、アーカイブ内のすべてのファイルを取得します。

Zip アーカイブを解析し、各エントリを識別してフィールドを解析し、データ セクションを復号化し、(zlib の .Net 実装から) DeflateStream を使用してそれらを解凍する小さなユーティリティ アプリを C# で作成しました。破損したエントリに到達するまで、すべてが正常に機能します。破損したエントリは (CTR モードで AES を使用して) 正常かつ完全に復号化されますが、DeflateStream リーダーは、「Bad state (oversubscribed dynamic bit lengths tree)」をスローする前に、復号化されたデータに約 40MB しか到達できません。

どうにかして破損したセクションを「シーク」し、データの解凍を続けることは可能ですか? いくつかの穴があっても、できるだけ多くのファイルを回復したいと考えています。DeflateStream は Seek メソッドを実装していません。基になる FileStream を最後の読み取り位置に配置して新しい DeflateStream を作成しようとすると、同じ「Bad State」例外がスローされます。

4

1 に答える 1

4

deflateプロトコルは、スライディングウィンドウとフォワードストリームに基づいてテーブルを適応させます。

これはブロックではありません。各セクションはスタンドアロンのデータ単位ではないため、不良ブロックを単に「スキップ」する方法はありません。むしろ、テーブル情報の計算/復元に使用されるストリームの移動する「ビュー」です。 。そうは言っても、私の単純な結論:現実的には不可能です:(

「Deflate」プロトコルの説明を参照してください。

不機嫌ではないデータの復元。


deflateプロトコルには、実際には、使用するコンプレッサーを切り替えることができる「ブロック」があります。しかし、私はそれらがどんな種類の回復にも使用できるとは思えません。これは、実際にはかなり回復可能なMPEG-4とはかけ離れています。

それがどれほど複雑になるかを示すRFC1951から:

ブロックは必ずしも整数のバイト数を占めるとは限らないため、ヘッダービットは必ずしもバイト境界で始まるとは限らないことに注意してください。

そして、個々のブロックにまたがることができるLZ77コンプレッサーについて話します:(圧縮情報を構築するために使用されるのは、ウィンドウ内のストリーム全体です)。

重複した文字列参照は、前のブロックの文字列を参照している可能性があることに注意してください。すなわち、後方距離は、1つまたは複数のブロック境界を横切る可能性がある。

ただし、希望のヒントがあります。

コンプレッサーは、新しいツリーで新しいブロックを開始することが有用であると判断した場合、またはブロックサイズがコンプレッサーのブロックバッファーをいっぱいにした場合に、ブロックを終了します。

私が追いかける光線ではありません:-/おそらく個々のビットシーク(すべてのビットシーケンスが有効なブロック開始であるとは限りません)そして失敗するまでアルゴリズムを実行し(おそらく「無効な」収縮)、その後バックオフしてそのようなまで再試行します開始ビットは、ある「許容可能な」期間内に無効な状態を生成しませんでした。

この方法では、deflateプロトコルエンジンを変更する必要があります。これは、通常のdeflateストリームプロセッサが処理できるタスクではありません。

于 2011-04-05T21:04:48.967 に答える