要約

  • RFC 1952 の gzip ファイルは連続するメンバーから成り、各メンバーが固有のヘッダー、圧縮ブロック、CRC32 と ISIZE のトレーラーを持つ。
  • 新しいメンバーの連結は既存バイトを書き換えず展開出力を増やす。ただし、索引やランダムアクセス、メンバーをまたぐ最適圧縮を与えるものではない。
  • 任意の名前や時刻は来歴証明ではなく、CRC32 は破損検出、ISIZE は 2^32 を法とする局所的な長さである。追加者の認証にはならない。

先頭のハッシュが変わらなくても内容は増える

昨日までのログを gzip で閉じたとする。今日の処理は、その末尾に新しい gzip ストリームだけを書き足す。昨日分のバイト列とハッシュは保存される。それでも先頭から展開する利用者は昨日と今日の両方を受け取る。

この動作の根拠は RFC 1952 にある。gzip ファイルは、余分な外側の情報を挟まず並ぶメンバーの系列である。メンバーはヘッダーから始まり、圧縮ブロックを経て、自分のトレーラーで終わる。終端はファイル全体の永久的な閉鎖ではなく、次の単位を認識可能にする局所的な閉鎖だ。

RFC Editor の記録では、P. Deutsch による文書は1996年5月公開の Informational RFC である。Standards Track の標準ではない。形式の規則は示すが、後世の全実装が同じ挙動をするという実測にはならない。

目標は、CPU、OS、ファイルシステム、文字集合を越える可搬性、限られた中間記憶でのストリーム処理、特許に妨げられない実装、既存 gzip との互換性だった。ランダムアクセスは対象外である。順番に継げることと、任意位置へ即座に飛べることは別の能力だ。

認識用の事実と説明用の主張

固定の二オクテットが gzip を識別し、CM=8 が DEFLATE を示す。FLG は任意フィールドの存在を宣言し、予約ビットはゼロでなければならない。ここは独立実装が同じ境界を歩くための必須合意である。

一方、MTIME は時刻、FNAME は元の名前、FCOMMENT は人向け注釈、FEXTRA は長さ付き拡張、FTEXT はテキストらしさを伝えうる。時刻ゼロは利用可能な時刻がないことを示し、OS 値は無視してもよい。未知の任意フィールドを読み飛ばせること自体が互換性条件だ。

したがって、FNAME は本人確認書類ではない。コメントは保管経路の署名ではない。時刻も現在のファイルへ追加された時刻を保証しない。外部の信頼関係があって初めて役立つ自己申告である。

FHCRC があれば、先行ヘッダーの CRC32 の下位16ビットを格納する。末尾の CRC32 は展開後データを対象にし、ISIZE は元入力長を 2^32 で割った余りである。ヘッダー検査、内容破損検出、長さ確認はそれぞれ別範囲を持つ。

余りは全体長ではない

ISIZE は32ビットで循環する。巨大入力では 2^32 の整数倍だけ異なる長さが同じ値になりうる。複数メンバーなら、各 ISIZE は自分の入力だけを語る。全展開長は読者が処理して合計する結果であり、最後のトレーラーに保存された総計ではない。

CRC32 の成功も認証ではない。偶発的な破損を発見する能力は高いが、任意のメンバーを作れる者は整合する CRC を作れる。「計算が一致した」と「許可された主体が書いた」は異なる命題だ。

圧縮表現も別層である。RFC 1951 が DEFLATE を定義し、RFC 1950 は同じ方式を別の zlib ラッパーと Adler-32 に収める。RFC 6713 は application/gzip と application/zlib を登録し、ファイル向けのヘッダー/トレーラーを持つ gzip と zlib ストリームを区別した。

コマンドごとに見える範囲が違う

GNU gzip の現行マニュアルは、圧縮済みファイルを連結すると gunzip が全メンバーを展開すると説明する。同時に、入力を先にまとめて圧縮する方が通常は効率的であり、--list の非圧縮サイズと CRC は最後のメンバーだけを表すと注意する。

同じソフトウェアでも、展開と一覧表示の契約は同じではない。監査が一覧値をファイル全体の値と呼べば、正しい局所情報から誤った全体保証を作ってしまう。

RFC 9110は HTTP の gzip 内容符号化を RFC 1952 参照で定義する。しかし、すべての中継、クライアント、検査器が複数メンバーを同じ範囲で扱うとは書いていない。その点は実装試験の領域だ。

小さな共通層が継続を可能にした

Running-Code Primacyに従えば、仕様の記号、実装、運用を混同しない。RFC は形式を、GNU マニュアルは一つの維持された実装を示す。普及率はこの証拠からは導けない。

Minimum Initial Specificationの観点では、識別子、方式、長さ、予約ビット、トレーラーは厳密でなければならない。一方、コメントを表示するか、OS ヒントを使うかは局所判断に残せる。

Reality Layersが分けるのは「一ファイル」という記号と、複数の開始・終了・検査を持つ実行構造である。gzip の名前は一つでも、閉じる瞬間は一つとは限らない。