ByteScope

XZ ファイル形式

XZ で圧縮されたデータ。通常は LZMA2 アルゴリズムを使います。

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

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

0x00000000FD377A585A00·7zXZ·XZ magic

XZ 形式について

XZ は LZMA2 を整合性チェック付きのコンテナに包んだもので、高い圧縮率が得られるためソフトウェア配布やカーネルイメージで使われます。6 バイトのマジックナンバーは FD 37 7A 58 5A 00 です。置き換えた先輩たちと違って、xz はストリームの上にヘッダを載せただけのものではなく、きちんとしたコンテナです。ストリームヘッダとそれに対応するストリームフッタがあり、ブロックはそれぞれ自分のヘッダと CRC を持ち、末尾には全ブロックの圧縮後・展開後サイズを列挙した索引があります。この索引のおかげで、リーダーは展開せずにファイルを検証したりシークしたりできます。そして同じ理由で、途中で切れた .xz はまったく検証できません。

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

オフセット長さフィールド意味
06Header magic bytesFD 37 7A 58 5A 00。バイト 1 から 4 は ASCII で 7zXZ と読め、これが 7-Zip の形式との混同を生み続けています。先頭の FD は意図的に ASCII の外に置かれていて、末尾の 00 はテキストモード転送を通したときにファイルがはっきり失敗するようにするためのものです。
62Stream flags1 バイト目は予約で 00 でなければなりません。2 バイト目の下位 4 ビットが整合性チェックの種類を示し、0 が無し、1 が CRC-32、4 が CRC-64、10 が SHA-256 です。標準ツールが書いたファイルは 00 04 と読めます。CRC-64 が既定だからです。
84CRC-32 of the stream flagsリトルエンディアンで、オフセット 6 の 2 バイトだけを対象にします。何もデコードしないうちに、どのチェック種別を適用すべきかをリーダーが信頼できるようにするために存在します。
121Block header size符号化されています。実際のサイズはこの値に 1 を足して 4 倍したものなので、04 なら 20 バイトのブロックヘッダです。ここが 00 なのは特別で、もうブロックが無く、このオフセットから索引が始まることを意味します。
131Block flags下位 2 ビットがフィルタ数マイナス 1、ビット 6 は圧縮後サイズのフィールドが続くこと、ビット 7 は展開後サイズのフィールドが続くことを示します。フィルタ 1 つで両方のサイズを持つ典型的なブロックは C0 と読めます。
variablevariableBlock sizes and filter flagsブロックヘッダの中で、この順に並びます。省略可能な圧縮後・展開後サイズを多バイトの可変長整数で、続いてフィルタチェーン(LZMA2 はフィルタ id 0x21 で、辞書サイズを符号化したプロパティバイトが 1 つ)、その後 4 の倍数までのゼロパディング、最後にブロックヘッダ自身の CRC-32 です。
variablevariableIndex最後のブロックの後ろに置かれ、ブロックごとに圧縮後・展開後サイズを記録したレコードが並び、4 の倍数までパディングされ、自身の CRC-32 が続きます。xz --list が読むのはこれで、xz が展開せずに中身を報告できるのもこのおかげです。
-124Stream footer CRC-32リトルエンディアンで、この後ろに続く 6 バイトのフッタを対象にします。フッタは固定 12 バイトなので、ZIP の終端レコードと違って後ろ向きに走査して探す必要はまったくありません。
-84Backward sizeリトルエンディアンで、実際の索引サイズはこの値に 1 を足して 4 倍したものです。索引が 12 バイトのファイルは 02 00 00 00 を格納します。ファイル末尾から索引を見つけられるようにしているのがこれで、つまりこの形式全体がシーク可能なのもこれのおかげです。
-42Stream flags (copy)オフセット 6 と 7 のバイト単位の複製で、末尾から読み始めたデコーダも、ヘッダが宣言したのと同じチェック種別を知ることができます。両者が食い違っていれば、そのファイルは改ざんされたか継ぎ接ぎされています。
-22Footer magic 'YZ'59 5A。無傷の .xz はどれもこの 2 バイトで終わります。ここが末尾でなければファイルは途中で切れており、前のほうにどれだけ正しそうなデータがあっても関係ありません。

似た形式との見分け方

紛らわしい形式見分け方
7-Zipこの形式が自ら招いた混同です。.xz は FD 37 7A 58 5A 00 で始まり、その中のオフセット 1 と 2 に 7z が居座っています。本物の .7z はオフセット 0 が 37 7A BC AF 27 1C です。つまり同じ 2 バイトが 1 つずれた位置で両方に現れるので、7z を雑に検索すると両方に一致します。関係のない形式です。.7z はディレクトリを持つ複数ファイルのアーカイブ、.xz は単一の圧縮ストリームです。
lzma (LZMA_Alone)先代であり、.lzma ファイルの識別が難しい理由でもあります。マジックナンバーがまったくありません。ヘッダは 13 バイトで、プロパティバイト 1 つ(たいてい 5D)、4 バイトのリトルエンディアンの辞書サイズ、8 バイトのリトルエンディアンの展開後サイズ(不明なら FF の繰り返し)という構成です。実際のファイルは 5D 00 00 80 00 に FF が 8 バイト続く形になり、これが署名にいちばん近い存在です。
GZIP1F 8B と FD 37 7A 58 5A 00 で、見た目以上に構造が離れています。gzip は索引を持たないストリームの上のヘッダですが、xz は末尾にブロック索引を保持するので、展開せずに一覧と検証ができます。
Zstandard現代のライバルです。28 B5 2F FD と xz のマジック。最高設定なら圧縮率は今も xz が小さいのですが、Zstandard は展開が数倍速く圧縮ははるかに速いので、パッケージマネージャが移行してきました。
TAR.tar.xz と、ファイル 1 つを xz したものは同じ形式です。展開して、結果のオフセット 257 が最初の 512 バイトの tar ヘッダの中で ustar になっているかを確認してください。.xz のコンテナ自体には両者を区別するものが何もありません。

よくある壊れ方

  • 途中切れ。索引もフッタも末尾にあるので、届いたブロックがすべてデコードできても、切れた .xz は一覧も検証もできません。ツールは想定外の入力終端を報告します。目視で確認するいちばん速い方法は、ファイル末尾の 2 バイトが YZ かどうかを見ることです。
  • ブロック本体のビット反転。既定の整合性チェックは CRC-64 なので破損は捕まりますが、捕まるのは展開のあとです。オフセット 8 の CRC-32 もブロックヘッダ自身の CRC も、対象はメタデータだけだからです。ひどく壊れたデータでは、チェックサムに到達する前に LZMA2 がデコードエラーで失敗するのが普通です。
  • 末尾の NUL バイトが削られた場合。ブロックとストリームは 4 の倍数までゼロバイトでパディングされるので、末尾の NUL を刈り取る転送やビルド処理は、フッタが依存しているアラインメントを壊します。ファイルは xz として認識され、最後の最後で失敗します。
  • 連結ストリームを 1 つとして解析してしまうケース。.xz の連結は合法で、間に省略可能なゼロパディングを挟むことも許されていて、標準ツールはそれらを全部展開します。最初のフッタマジックで止める自作リーダーは、その後ろを黙って捨てます。
  • テキストモード転送。ヘッダのマジックにある 00 は、これを即座に失敗させるために置かれていて、実際そうなります。ただし同じ変換がストリームのもっと奥で起きた場合はヘッダが無傷で残るので、ファイルは正しく認識され、デコードが破損箇所に届いたときにだけ失敗します。

この形式の現在地

XZ は、一度圧縮して何度もダウンロードされるファイルで、ダウンロードのほうが高くつく場面のための形式です。カーネルの tarball、ディストリビューションのパッケージ、ソースのリリース、コンテナのベースレイヤーは 10 年以上これに頼ってきました。高いプリセットでの LZMA2 は、今もよくある形式の中で汎用の出力としては最小になるからです。代償は本物です。圧縮は遅く、メモリを非常に大量に食いますし、展開時のメモリも書き手が選んだ辞書サイズに比例します。プリセット 9 で作ったアーカイブを開くには 64 MB ほど必要で、組み込み環境では本当に問題になります。それに加えて数倍の速度差があり、2019 年ごろからパッケージマネージャやファイルシステムで Zstandard が着実にその座を奪ってきました。xz が第一候補であり続けるのは、静的なコンテンツを帯域に律速される形で配る場面です。繰り返し書き込むものやライブでストリーミングするものには向きません。

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

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

関連する形式

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

形式先頭バイト拡張子
GZIP1F 8B.gz
BZIP242 5A 68.bz2
Zstandard28 B5 2F FD.zst
7-Zip37 7A BC AF 27 1C.7z

よくある質問

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

ファイル先頭の数バイトで、名前が何であろうとその形式を示すものです。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 でも悪意のあるペイロードを含んでいることがあります。特に拡張子とバイト列が食い違うときに真の形式を知るのは有用な第一段階ですが、マルウェアスキャンではありません。

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