1

圧縮されたコンテンツと 32 バイトのヘッダーで構成されるファイルがあります。ヘッダーには、タイムスタンプ、圧縮サイズ、非圧縮サイズなどの情報が含まれています。

ファイル自体は約 490mb で、ヘッダーは非圧縮サイズが 2.7gb に近いことを示しています (圧縮サイズが 752mb であると信じているため、明らかに誤りです)。

ヘッダーを取り除き、圧縮されたペイロードを生成しました。zlib で圧縮解除できます。

問題は、490mb よりもはるかに小さい 19kb のみを解凍していることです (最低限必要ですが、非圧縮で約 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 を生成します...それが少なすぎます。

ポインタや提案は大歓迎です!

4

2 に答える 2

3

明らかにファイルが破損しています。

zlib に破損を強制的に無視させることはできません。無視した場合、700MB のガベージ、またはランダムな量のガベージが発生する可能性が高くなります。どこ。しかし、何か役に立つものを入手できる可能性はかなり低いです。

zlibのブロックは、ランダムにアクセスできず、区切られておらず、バイト単位で整列されていません。前のブロックを処理できなければ、次のブロックにいつ到達したかを判断するのは非常に困難です。

さらに、木はブロックからブロックへと成長するため、次のブロックにスキップできたとしても、木は間違っていて、非常に幸運で壊れた部分が必要ない場合を除き、ゴミを解凍することになります.木。さらに悪いことに、どのブロックでもツリーを再起動できます (またはコンプレッサーを切り替えることさえできます)。それを逃す、運が良かったとしてもゴミを解凍していることになりますそして、「この文字列は認識できないので飛ばしてください」というだけではなく、認識しなければ文字列が何ビットの長さなのかもわからないので、飛ばすことはできません。これは最初のポイントに戻ります — ブロック全体どころか、1 つの文字列をスキップすることさえできません。

これをよりよく理解するには、 で使用される形式について説明しているRFC 1951zlibを参照してください。いくつかの些細な例 (最初のブロックにいくつかの文字列、2 番目のブロックにいくつかの新しい文字列) を手動で試してみて、元に戻すのが難しい方法でそれらを破損するのがいかに簡単かを確認してください (その方法を正確に知っている場合を除きます)。破損していました)。不可能ではありません (暗号化されたメッセージを解読することは不可能ではありません) が、完全に自動化できるとは思えません。

重要なデータを持っている場合 (そして、再ダウンロード、以前のバージョンへのロールバック、バックアップからの復元などができない場合)、一部のデータ復旧サービスは、破損した zlib/gz/zip ファイルを復旧できると主張しています。 . これには腕と脚のコストがかかると思いますが、正しいデータに対する正しい答えかもしれません。

そしてもちろん、これが自動化されていないことについて私は間違っている可能性があります。そこにはたくさんのzip回復ツールがあります。私の知る限り、壊れた zlib ストリームに対して彼らができることは、そのファイルをスキップして他のファイルを復元することだけです。

于 2013-03-29T00:12:00.960 に答える
0

zlib.error停止した理由を確認する必要があります。なぜ停止したのですか?

于 2013-03-29T00:53:20.117 に答える