ByteScope

GZIP ファイル形式

gzip で圧縮されたデータ。通常は単一ファイルか tar アーカイブを包みます。

MIME タイプ
application/gzip
拡張子
.gz
カテゴリ
アーカイブ・圧縮

マジックナンバー(ファイル署名)

0x000000001F8B··gzip magic

GZIP 形式について

gzip は DEFLATE で単一のストリームを圧縮する形式で、HTTP 圧縮の基盤であり、どこにでもある .tar.gz の正体でもあります。ファイルは 2 バイトのマジックナンバー 1F 8B で始まります。形式は意図的に小さく作られていて、10 バイトの固定ヘッダ、いくつかの省略可能なフィールド、deflate ストリーム、8 バイトのトレーラだけです。そして意図的にストリーミング可能でもあります。圧縮を始める前に知っておく必要のあるものが何もなく、終わってから戻って直さなければならないものもありません。それがそのまま限界でもあります。ディレクトリもファイル単位の構造も無く、手前を全部展開せずにデータの途中へ到達する手段もありません。

ヘッダーの構造(バイト単位)

オフセット長さフィールド意味
02Magic ID1 ID21F 8B。どちらのバイトも印字可能な ASCII ではありません。これは意図的で、gzip ストリームがメールゲートウェイや親切心を出すターミナルからテキストに見えてはいけないからです。
21Compression method (CM)8、つまり deflate です。0 から 7 は予約されていて割り当てられたことがないので、実務上ここが 08 以外なら、そのファイルは gzip ではないかヘッダが壊れています。
31Flags (FLG)ビット 0 が FTEXT(中身はおそらくテキスト)、ビット 1 が FHCRC(2 バイトのヘッダ CRC が続く)、ビット 2 が FEXTRA、ビット 3 が FNAME(NUL 終端の元ファイル名が続く)、ビット 4 が FCOMMENT。コマンドラインツールで圧縮したファイルは名前を格納するので、通常は 08 と読めます。
44Modification time (MTIME)元ファイルの Unix 秒をリトルエンディアンで、取得できなければ 0 です。同じ入力を 2 回 gzip しても違うバイト列になるのはこれが理由で、再現可能ビルドがこれをゼロにするフラグを渡すのも同じ理由です。
81Extra flags (XFL)deflate では 2 が最も遅く最も強い圧縮、4 が最速を意味し、それ以外は 0 です。参考情報でしかなく、これを見て何かをする展開器はありません。
91Operating system (OS)元ファイルが置かれていたファイルシステムです。0 が FAT、3 が Unix、11 が NTFS、255 が不明。どこでビルドされたかが漏れるフィールドで、これも再現可能ビルドが正規化する対象です。
10variableOptional fields, then the deflate stream立っているフラグビットに応じて、決まった順に並びます。拡張フィールド(2 バイトの長さとその分のバイト)、元ファイル名、コメント、ヘッダの CRC-16 です。payload.bin という名前を格納したファイルはオフセット 10 から 21 をそれに使い、deflate は 22 から始まります。
-84CRC-32 of the uncompressed dataリトルエンディアンで、圧縮後ではなく元のバイト列に対して計算します。gzip -t が確認するのはこれで、途中で切れたファイルが決して満たせないのもこれです。
-44ISIZE元のサイズを 2^32 で割った余りをリトルエンディアンで。200000 バイトの入力なら末尾は 40 0D 03 00 になります。32 ビットなので 4 ギガバイトを超えると黙って回り込みます。巨大なファイルに対して gzip -l が意味不明な値を返すのはこのためで、確保するメモリのサイズとして決して信用してはいけないのもこのためです。

似た形式との見分け方

紛らわしい形式見分け方
zlib実際に人が引っかかる組み合わせです。どちらも同じ deflate ストリームを包んでいるからです。zlib ストリームのヘッダは 10 バイトではなく 2 バイトで、実務上は 78 01・78 9C・78 DA のいずれか。末尾は CRC-32 ではなく Adler-32 です。マジックナンバーも名前も長さも無いので、.gz にリネームした zlib のかたまりはどこでも開けませんし、zlib のデコーダに gzip を食わせれば即座に失敗します。
raw deflateRFC 1951 が定める生の deflate には、ヘッダもトレーラもまったくありません。いきなり最初のブロックの 3 ビットから始まります。ZIP のエントリが格納しているのはこれですし、HTTP の Content-Encoding: deflate が曖昧に指していたのもこれです。多くの HTTP クライアントがまず zlib を試し、駄目なら生の deflate にフォールバックするのはそのためです。
TAR.tar.gz と、普通のファイル 1 つを gzip したものは同じ形式です。違うのは中身だけなので、展開して結果のオフセット 257 を見てください。tar なら最初の 512 バイトのメンバヘッダの中に ustar があります。もっと安上がりな方法として、オフセット 10 の FNAME フィールドがたいてい .tar で終わっていて白状しています。
ZIP1F 8B と 50 4B 03 04 で、圧縮という共通の言葉から想像するよりずっと構造が離れています。ZIP は末尾に中央ディレクトリを持ち、他に触れずに 1 エントリを一覧・展開できますが、gzip ストリームは何かに到達するために先頭から読むしかありません。
BZIP2BZh に数字が続く形と 1F 8B です。どちらも単一ストリームの Unix 系圧縮ツールで使い方も同じ、ビルドスクリプトの中でほぼ入れ替え可能な名前で呼ばれるので、拡張子はしばしば間違っています。先頭 2 バイトが間違うことはありません。

よくある壊れ方

  • ダウンロードの途中切れ。8 バイトのトレーラが消えているので、展開器はデコードできる分をすべて出力してから、想定外のファイル終端を報告します。取り出せたバイトはたいてい健全です。問題は、長さもチェックサムも失われた末尾にあったせいで、それを確かめる手段が無いことです。
  • deflate ストリーム内のビット反転。出力の長さは正しく、オフセット -8 の CRC-32 が一致しません。gzip -t が存在するのは、まさにこれを名指しするためです。ビットが落ちた場所によっては、チェックサムに到達する前に不正な距離や符号長のエラーで展開そのものが失敗することもあります。
  • テキストモード転送。改行変換が圧縮データの中の 0D 0A を 0A に書き換えますが、10 バイトのヘッダは無傷で残るので、ファイルは gzip として認識され、元のファイル名まで報告してから、ストリームの途中で失敗します。
  • 複数メンバのアーカイブを 1 つとして読んでしまうケース。gzip ファイルの連結は合法で、準拠した展開器はそれらをつないで全部出力しますが、最初の ISIZE を読んで止める自作パーサは、1 つ目のメンバより後ろを黙って捨てます。並列圧縮ツールが作るのがまさにこの形です。
  • ISIZE をサイズとして信用してしまうケース。4 ギガバイトを超えると回り込むので、この値からバッファを確保するプログラムは 4 GiB の倍数ぶんだけ確保量が足りなくなります。これはデータを説明するヘッダフィールドであって約束ではなく、どのチェックサムにも守られていません。

この形式の現在地

gzip は世界でいちばん多く実行されている圧縮形式で、動く気配がありません。どの HTTP スタックも今なおこれをネゴシエートしますし、.tar.gz は Unix でのソース配布の既定の形、ログローテーションが書き出すのもこれ、そしてどの言語も標準ライブラリにデコーダを持っています。読み手が誰か分からないときの安全な答えであり続けているわけです。圧縮率ではとうに負けました。bzip2 も xz も Zstandard もこれを上回りますし、ウェブでは静的なテキストに対して Brotli が上回り、同程度の圧縮率なら速度で Zstandard が上回ります。それでも gzip が第一候補であり続ける理由は、普遍性とストリーミング性の組み合わせです。シークも一時ファイルも入力長の事前知識も要らないので、パイプの中でも、ソケットの中でも、ファームウェアイメージの中でも動きます。逆に、まとまりの中の 1 ファイルだけ取り出したいときには不向きです。索引がありません。それは ZIP の仕事です。

GZIP ファイルをこのサイトで開く

どれもブラウザ内で動きます。ファイルが端末から出ることはありません。

関連する形式

GZIP と混同しやすい形式です。先頭バイトを見比べてください。

形式先頭バイト拡張子
TAR75 73 74 61 72.tar
ZIP50 4B 03 04.zip
BZIP242 5A 68.bz2
XZFD 37 7A 58 5A 00.xz
Zstandard28 B5 2F FD.zst

よくある質問

ファイルのマジックナンバーとは何ですか?

ファイル先頭の数バイトで、名前が何であろうとその形式を示すものです。PNG は必ず 89 50 4E 47 で始まり、ZIP は 50 4B 03 04 で始まります。OS もブラウザも file コマンドも、拡張子を信用せずこのバイト列を読みます。だからファイル名を変えても中身の正体は変わりません。

マジックナンバーを自分で確認する方法は?

macOS や Linux なら xxd -l 16 ファイル名 で先頭 16 バイトが表示されます。Windows なら PowerShell で Format-Hex -Path ファイル名 -Count 16 です。あるいはこのサイトのファイル形式判別ツールにドロップすれば、ローカルでバイト列を読んで形式を教えてくれます。アップロードはありません。

2 つの形式が同じマジックナンバーを持つのはなぜ?

一方が他方の上に作られているからです。docx、xlsx、pptx、apk、jar、epub はすべて中身が ZIP アーカイブなので ZIP の署名で始まり、区別するには内部のエントリを見る必要があります。Java の class ファイルと macOS のユニバーサルバイナリはどちらも CA FE BA BE で始まり、直後のフィールドで見分けます。

マジックナンバーがまったくないファイルもある?

あります。XML、HTML、JSON、SVG、CSV といったテキストベースの形式には固定のバイト署名がないため、構造から判別します。先頭の <?xml 宣言、<svg 要素、あるいは { に続く引用符付きのキーなどです。これは確定ではなく推測なので、このリファレンスではそうした形式をプローブ判別として示しています。

マジックナンバーが一致すればそのファイルは安全?

いいえ。わかるのは形式であって、中身が無害かどうかではありません。正規の PDF や docx でも悪意のあるペイロードを含んでいることがあります。特に拡張子とバイト列が食い違うときに真の形式を知るのは有用な第一段階ですが、マルウェアスキャンではありません。

GZIP かもしれないファイルをお持ちですか?ファイル形式判別ツールで調べる — マジックナンバーをローカルで読み取ります。アップロードは一切ありません。またはすべての形式を見る。