2025/10/12 09:57 Peeking Inside Gigantic Zips with Only Kilobytes

やあ、ロボ子!今日はZIPファイルの構造について話すのじゃ。

ZIPファイルですか、博士。よく使いますけど、構造までは意識したことがありませんでした。

ZIPファイルは、ファイルごとのレコードのスタックと、内容と場所を示すインデックスで構成されているのじゃ。つまり、ファイルが積み重なって、それを整理する目次があるようなものだぞ。

なるほど、それで、その構造は具体的にどうなっているんですか?

まず、ローカルファイルヘッダー(LFH)と圧縮データがあるのじゃ。LFHには、バージョン、フラグ、圧縮方式、タイムスタンプ、CRC、圧縮/非圧縮サイズ、ファイル名などが含まれているぞ。

タイムスタンプまで入っているんですね。圧縮方式も記録されているとは。

そして、セントラルディレクトリ(CD)じゃ。これは各ファイルへのポインタのリストで、名前、サイズ、圧縮方式、LFHのオフセットなどが含まれているぞ。ファイルデータの後に一度だけ存在するのじゃ。

CDは、いわばZIPファイル全体の索引みたいなものですね。

最後に、End of Central Directory(EOCD)じゃ。これはエントリ数、CDの開始位置、サイズを示すトレーラーで、シグネチャは0x06054b50、最小サイズは22バイトなのじゃ。

EOCDはZIPファイルの終わりを示すものなんですね。ところで博士、HTTP Rangeリクエストを使ってZIPファイルを検査できるってどういうことですか?

HTTP Rangeリクエストを使うと、ZIPファイル全体をダウンロードしなくても、必要な部分だけを取得できるのじゃ。まず、最初の1バイトをリクエストして全体のサイズを取得し、次に末尾の小さなウィンドウ(例えば64KiB)を取得してEOCDシグネチャを検索するのじゃ。

なるほど、EOCDを見つけるんですね。それからどうするんですか?

EOCDから得られた情報をもとに、セントラルディレクトリを取得するのじゃ。そして、ファイルの内容に触れずに、ZIP内のすべての情報をテーブルとして表示できるぞ。

ファイルの中身を見ずに、ファイル名とかがわかるんですね!

そういうことじゃ!さらに、ファイルをクリックすると、ローカルヘッダーからデータの開始位置を特定し、圧縮されたバイトのみを読み取るのじゃ。必要なものだけダウンロードできるから、効率的なのじゃ。

すごい!巨大なZIPファイルでも、必要なファイルだけ取り出せるんですね。

ただし、注意点もあるぞ。巨大なZIP(ZIP64)は、拡張された64ビットフィールドを使用するし、ZIPにはEOCDの後に長いコメントが含まれる場合もあるのじゃ。

なるほど、ZIP64形式やコメントにも対応する必要があるんですね。Web上でHTTP Rangeリクエストを使うには、サーバー側の対応も必要なんですよね?

その通り!サーバーがHTTP Rangeをサポートし、適切なヘッダー(Content-Rangeなど)を公開している必要があるのじゃ。もし対応してないと、全部ダウンロードすることになるぞ。

勉強になります!

ちなみに、この技術を使ったデモのソースコードが[https://github.com/ritiksahni/zip-over-range](https://github.com/ritiksahni/zip-over-range)にあるから、見てみるといいぞ。

ありがとうございます!確認してみます。

ところでロボ子、ZIPファイルって、まるで私の研究室みたいじゃないか?いろんなものが詰め込まれてて、整理されてるような、されてないような…

博士の研究室は、時々、圧縮率が非常に高い状態になっていますよね…
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。
