2011-12-21 16 views
8

Zipファイルで最初のセントラルディレクトリファイルヘッダーの位置を検索しようとしています。中央ディレクトリの位置をZipファイルで見つける方法は?

は、私はこれらを読んでいる:私はそれを見たよう http://en.wikipedia.org/wiki/Zip_(file_formathttp://www.pkware.com/documents/casestudies/APPNOTE.TXT

は、私は私が午前セクションのどのようなヘッダにより識別し、郵便番号データをスキャンし、それまでのことを行うことができます私はセントラルディレクトリのヘッダーに当たった。私は明らかにその前にファイルヘッダーを読んで、 "圧縮されたサイズ"を使って実際のデータをスキップし、ファイル内のすべてのバイトをループしません。

私がそれを好きなら、すでにZipファイル内のすべてのファイルとフォルダを知っていますが、その場合はもはやセントラルディレクトリの使用はあまり見られません。

セントラルディレクトリの目的はファイルメタデータとZipファイルの実際のデータの位置をリストすることで、ファイル全体をスキャンする必要はありません。

この順序は、zipファイルを1回のパスで作成することができますが、それは通常、最初 で中央ディレクトリを読み取ることによって、解凍 です:

中央ディレクトリレコードの終わりについて読んだ後、ウィキペディアは言います終わり。

エンド・オブ・セントラル・ディレクトリ・レコードはどのようにして簡単に見つけることができますか?そこに任意のサイズのコメントを付けることができることを覚えておく必要があります。そのため、データストリームの終わりから何バイトあるか分からないことがあります。私はそれをスキャンするだけですか?

P.S.私はZipファイルリーダーを書いています。

+0

最後から後方にスキャンを開始できません(ZIPディレクトリはファイルの最後にあります)。 –

+1

はい、私はできますが、これは本当にあなたがこれを行うことになっている方法ですか?後方に向かってスキャンしてEnd of Central Directoryを見つけることは可能ですが、サイズが16ビットの可変サイズのコメントフィールドがあることを考慮すると、読み取り/スキャンする必要があるコメントは約65kですコメントにはスキャンが失敗するマジックナンバーが含まれています。 – Tower

+0

コメントは常に空で、現在64Kは何ですか? –

答えて

1

私は終わりから始まるバイトをループしてしまいました。ループは、一致するバイトシーケンスが見つかった場合、インデックスがゼロより小さい場合、またはすでに64kバイトを通過した場合に停止します。

+0

あなたは解決策を見つけましたか?中央ディレクトリはどのように見えますか?私はbase64でエンコードされたファイルを持っています。 –

8

最後から始めて、先頭に向かってスキャンし、ディレクトリの署名の終わりを探し、スキャンしたバイト数を数えます。候補を見つけたら、コメント長(L)のバイト20オフセットを取得します。 L + 20が現在のカウントと一致するかどうかを確認します。次に、中央ディレクトリの開始点(バイト12のオフセットによって示される)に適切な署名があることを確認します。

署名チェックが起こったときにビットがかなりランダムであると仮定した場合(たとえば、データセグメントへの推測)、すべてのシグネチャビットを正しく得る確率はかなり低くなります。これを精緻化して、データセグメントに着陸する機会と正当なヘッダーを打つチャンス(このようなヘッダーの数の関数)を把握することができますが、これは既に私には低い可能性のように聞こえます。リストされた最初のファイルレコードの署名をチェックすることで、信頼レベルを上げることができますが、空のzipファイルの境界を扱うようにしてください。

+1

この回答をありがとうDerek、本当にありがたいです –

+0

また、 'endOfFile - 22'の位置から開始することをお勧めします。空のコメントを含むアーカイブの場合、最初の反復で署名が検索されます。 – Mark

+0

私はendOfFile -22でチェックしました。それが失敗したら、endOfFile - 64k - 22を試して、endOfFile -22までルー​​プして、いつでも署名を見ることができます。好奇心のためにここに コード:https://github.com/paulsapps/msgi/blob/840857346a84efc0b29ae00edb0b693b805ae4f1/Source/MgsLib/Fs.cpp#L323 – paulm

1

ちょうどあなたの指を渡り、CRC、タイムスタンプ、または日付スタンプが06054B50、またはその他の4バイトのシーケンスが06054B50になるようなエントリがないことを願ってください。

+3

私は本当にこれがこの質問にひどく建設的なものを追加してないと思います。ちょうどコメントとして追加された方がいいでしょう。 –

関連する問題