7-Zip ファイル形式
7-Zip アーカイブ。LZMA/LZMA2 により高い圧縮率が得られます。
- MIME タイプ
- application/x-7z-compressed
- 拡張子
- .7z
- カテゴリ
- アーカイブ・圧縮
マジックナンバー(ファイル署名)
| 0x00000000 | 377ABCAF271C | 7z··'· | 7z magic |
7-Zip 形式について
7z は 7-Zip のネイティブ形式で、強力な LZMA2 圧縮、ソリッドアーカイブ、AES-256 暗号化に対応します。署名は 37 7A BC AF 27 1C です。固定の配置は先頭 32 バイトですべてです。署名、フォーマットのバージョン、そして本当のヘッダがある場所へのポインタ。それ以外のもの、つまりファイル名、サイズ、タイムスタンプ、チェックサム、そしてデータがどう符号化されたかの記述は、すべてファイルの反対側の端にあるそのヘッダの中にあり、たいていそれ自体も圧縮されています。その間にファイルごとのヘッダは一切存在しません。それが .7z をコンパクトにしている理由であり、壊れたときに ZIP よりはるかに救い出しにくい理由でもあります。
ヘッダーの構造(バイト単位)
| オフセット | 長さ | フィールド | 意味 |
|---|---|---|---|
| 0 | 6 | Signature | 37 7A BC AF 27 1C。先頭 2 バイトは ASCII の 7z なので読めるテキストとして現れます。残りの 4 バイトは、テキストファイルが一致しようのないように選ばれた任意のバイナリです。 |
| 6 | 1 | Format major version | これまでに書かれたどのアーカイブでも 0 です。ここが変わることは構造的に非互換な形式を意味するので、リーダーはそれ以外の値を警告ではなく拒否として扱います。 |
| 7 | 1 | Format minor version | 今のアーカイブでは 4 です。マイナーバージョンは後方互換な追加なので、0.4 を理解できるリーダーはそれより古いものをすべて扱えます。 |
| 8 | 4 | Start header CRC-32 | リトルエンディアンで、オフセット 12 から 31 のちょうど 20 バイトを対象にします。他のすべてが依存するポインタを守るためのもので、どこかへシークする前に、先頭部分の破損か本体の破損かをリーダーが判断できます。 |
| 12 | 8 | Next header offset | 本当のヘッダへのリトルエンディアン 64 ビットのオフセットで、ファイル先頭からではなく、この署名ヘッダの終わりであるオフセット 32 から数えます。200246 バイトのアーカイブでは F4 0D 03 00 00 00 00 00、つまり 200180 と読めるので、ヘッダは 200212 から始まります。 |
| 20 | 8 | Next header size | そのヘッダの長さをリトルエンディアン 64 ビットで。オフセットと合わせて、ちょうどファイルの終端に着地しなければなりません。32 足す 200180 足す 34 は 200246 で、これがファイルの実サイズです。この算数がいちばん手軽な整合性チェックです。 |
| 28 | 4 | Next header CRC-32 | 手前の 2 つのフィールドが指すヘッダのチェックサムをリトルエンディアンで。解析を試みる前に、そこの破損を検出できます。 |
| 32 | variable | Packed streams | 圧縮データそのもので、32 バイトの署名ヘッダの直後に書かれます。ソリッドアーカイブではこれがファイルごとに 1 本ではなく、多数のファイルにまたがる連続した符号化ストリーム 1 本になります。 |
| variable | variable | Header | オフセット 32 に next header offset を足した位置にある、アーカイブの本当のディレクトリです。名前、サイズ、CRC、タイムスタンプ、属性、そして packed streams のデコード手順を記述するコーダチェーンが入ります。通常はそれ自体が LZMA で圧縮されていて、ヘッダ暗号化を有効にしていれば暗号化もされています。 |
似た形式との見分け方
| 紛らわしい形式 | 見分け方 |
|---|---|
| XZ | 実際に事故を起こすのがこれです。.xz は FD 37 7A 58 5A 00 で始まるので、オフセット 1 に 37 7A が現れ、hex ダンプには ASCII の 7zXZ がはっきり見えます。本物の .7z はオフセット 0 が 37 7A BC AF 27 1C です。1 つずれた位置に同じバイトがある、無関係な 2 つの形式です。.7z はディレクトリを持つ複数ファイルのアーカイブ、.xz は単一の圧縮ストリームです。 |
| ZIP | 共通するバイトはありません。50 4B 03 04 と 37 7A BC AF 27 1C。それでも同じツールが両方を書くので、ラベルの取り違えは絶えません。構造上の違いはディレクトリの場所と、それにかかるコストです。ZIP は 1 エントリの一覧と展開が安上がりですが、ソリッドな .7z は 1 ファイルに到達するために数ギガバイトをデコードしなければならないことがあります。 |
| RAR5 | もうひとつの高圧縮率な Windows 系アーカイバで、52 61 72 21 1A 07 01 00 で始まります。真正面から競合していて、実務上の違いは、7z が公開されていて自由に実装できるのに対し RAR は独占的であること、そして RAR にはリカバリレコードがあり 7z には無いことです。 |
| Self-extracting .exe | 7-Zip の SFX アーカイブは Windows の実行ファイルにアーカイブを追記したものなので、オフセット 0 は 4D 5A(MZ)と読め、37 7A BC AF 27 1C の署名はファイルのずっと奥に座っています。署名を走査して探す 7z リーダーなら問題なく展開できますし、.exe をアーカイブとして安全に開けるのはそのためです。 |
よくある壊れ方
- 途中切れ。ZIP のときよりはるかに深刻です。先頭 32 バイトにある next header offset がファイル末尾より先を指してしまうので、一覧すら出せません。しかも ZIP と違って前方に走査すべきファイルごとのローカルヘッダがありません。.7z にはそもそも存在しないからです。部分復旧はたいてい、コーダチェーンを手で推測する作業になります。
- オフセット 8 のスタートヘッダ CRC の失敗。先頭 32 バイトが壊れているということで、実務上これはほぼ必ず、その場でビットが反転したのではなく前にバイトが付いたか削られたかを意味します。あのブロックは小さく、めったに触れられないからです。
- ソリッド圧縮による局所的な破損の増幅。既定では多数のファイルが 1 本の連続したストリームとして圧縮されるので、ソリッドブロックのどこか 1 バイトが壊れると、そのブロック内でそれより後ろのファイルがすべて失われます。ソリッドモードを無効にして作ったアーカイブは、まさにこの封じ込めと引き換えに圧縮率を差し出しています。
- 暗号化されたヘッダを破損と取り違えるケース。ヘッダ暗号化ありで作られたアーカイブは、パスワードなしにはファイル名の一覧すら出せないので、ツールは読めないと報告するか、何も表示しません。アーカイブは完全に無傷で、答えることを拒んでいるだけです。
- テキストモード転送。32 バイトの署名ヘッダは生き残るので、アーカイブは正しく認識されヘッダのポインタも解決します。失敗が現れるのは、packed streams を実際にデコードしたときの CRC エラーとしてだけです。
この形式の現在地
7z は主流のデスクトップ向けアーカイバの中では圧縮率の王者で、Windows では ZIP が大きすぎるときに手が伸びる先です。ソリッドブロックを使った LZMA2 は、ソースツリーや文書のまとまりに対して ZIP の出力を日常的に半分にしますし、AES-256 の暗号化も後付けではなく最初から組み込まれています。仕様は公開されていてリファレンス実装も自由に使えるので、libarchive も p7zip もたいていのアーカイブツールも読めます。ならなかったのは交換形式です。Unix のパーミッションやシンボリックリンクを一級で扱うモデルが無く、ソリッド圧縮のせいで 1 ファイルだけの展開が非常に高くつくことがあり、ファイルごとのヘッダが皆無なので壊れたアーカイブは壊れた ZIP よりずっと救いにくくなります。Unix で同じ仕事をするのは tar.xz や tar.zst で、こちらはパーミッションのモデルを tar の層に残します。そして相手が誰か分からないまま開いてもらうものについては、今も ZIP が安全な答えです。
7-Zip ファイルをこのサイトで開く
どれもブラウザ内で動きます。ファイルが端末から出ることはありません。
関連する形式
7-Zip と混同しやすい形式です。先頭バイトを見比べてください。