DEFLATE 與 Gzip 格式

最後更新: 2023-09-27 03:10:18 +0800 +0800
原文以英文撰寫。您正在閱讀AI翻譯版本。

DEFLATE 是 RFC 1951 定義的位元流格式。它結合 LZ77 滑動視窗與霍夫曼 編碼。「zlib」和「gzip」通常指包含 DEFLATE 的檔案,但兩者分別是包覆 原始位元流的不同封裝格式。

區塊邊界與 BTYPE #

DEFLATE 串流由一連串區塊組成。每個區塊都從目前的位元位置開始,包含 BFINAL(1 位元)和 BTYPE(2 位元):

BTYPE意義
00未使用霍夫曼編碼的儲存位元組
01使用固定霍夫曼編碼壓縮
10使用動態霍夫曼編碼壓縮
11保留值,無效

只有最後一個區塊的 BFINAL 為 1。當文字/長度串流輸出區塊結束 (EOB)符號 256 時,壓縮區塊就會結束。下一個區塊標頭會緊接在下一個 位元處;壓縮區塊不會填補到位元組邊界。儲存區塊是例外:讀取標頭後, 解碼器會捨棄目前位元組中的剩餘位元,讀取小端序的 LEN 和 NLEN (LEN 的一補數),然後正好複製 LEN 個位元組。LEN 為 16 位元, 因此單一儲存區塊最多可容納 65,535 個位元組。

LZ77 符號與霍夫曼編碼 #

壓縮資料字母表包含文字位元組 0–255、EOB 256,以及長度符號 257–285。 長度符號會選取基礎長度與額外位元數。接續的距離符號會選取基礎距離與 額外位元數。產生的配對會從已產生的輸出向後複製位元組,最遠 32 KiB, 長度最多 258 個位元組;重疊是有效的。

固定區塊使用 RFC 1951 規定的編碼長度。動態區塊包含 HLIT(5 位元)、 HDIST(5 位元)和 HCLEN(4 位元),接著依指定排列傳送編碼長度 字母表。該字母表描述文字/長度編碼與距離編碼的編碼長度,包括用於表示 連續零或重複長度的重複符號。透過正規重建,可將這些長度轉換為實際編碼。

DEFLATE 在每個位元組內由最低有效位元向最高有效位元封裝資料元素。 數值型額外位元欄位採用最低有效位元優先順序。霍夫曼編碼會以正規值分配, 但輸出時遵循該格式規定的位元反轉慣例。剖析器必須維護位元游標,而不能 將每個欄位都當作位元組對齊的整數讀取。

zlib 與 gzip 封裝格式 #

原始 DEFLATE 沒有標頭或尾端。zlib 封裝格式(RFC 1950)以 CMF 和 FLG 開始,其中 FCHECK 確保 16 位元標頭可被 31 整除。如果設定 FDICT,後面會接著一個四位元組的 Adler-32 字典識別碼。串流以未壓縮 資料的大端序 Adler-32 結束。

gzip 封裝格式(RFC 1952)是一連串成員。每個成員都有魔術位元組 1f 8b、 壓縮方法 8、旗標、修改時間、額外旗標和作業系統欄位。旗標可以加入額外 欄位、原始檔名、註解和標頭 CRC。尾端儲存未壓縮成員的小端序 CRC-32, 以及 ISIZE,即其大小對 2³² 取模的結果。中繼資料不能取代對尾端的驗證。

協定文件必須明確指出表示形式。HTTP Content-Encoding: gzip 攜帶 gzip 格式,而使用 method 8 的 ZIP 項目通常攜帶原始 DEFLATE 串流。不能僅因 某個承載被描述為「compressed」,就安全地選擇 zlib 解碼器。

參考資料 #

評論

在 GitHub 上閱讀或評論(發表評論需要登入)