Unix compress 與 LZW

最後更新: 2025-04-04 21:50:25 +0800 +0800
tags: Compression | Unix | Lzw
原文以英文撰寫。您正在閱讀AI翻譯版本。

歷史悠久的 Unix compress 工具會寫入通常命名為 .Z 的檔案。它使用 LZW 系列字典編碼器,而非 DEFLATE。uncompress 與 zcat 在提供此格式的系統上公開相容的命令列介面。

LZW 初始化與同步 #

LZW 編碼器會從單位元組字母表的項目開始。它會保留目前片語 w,讀取下一個位元組 k,並在該片語仍位於字典中時 w + k 持續處理。當該片語不存在時,它會輸出 w 的代碼,加入 w + k,並以 k 開始。解碼器會輸出每個代碼所代表的字串;在第一個代碼之後,它會加入前一個解碼字串與目前字串第一個位元組的組合。輸入耗盡後,編碼器會輸出其最後片語。因此,編碼器與解碼器會在落後一個代碼的位置加入相同的項目。

熟悉的 KwKwK 情況發生在某個代碼等於下一個字典索引時:解碼器會將其展開為 previous + first(previous)。拒絕這種情況會拒絕有效的串流;接受超過下一個索引的任何代碼則會使字典失去同步。

.Z 位元串流 #

.Z 串流以 1f 9d 和一個旗標位元組開頭。低五個位元指定最大代碼寬度,通常為 9 到 16 位元。位元 7 啟用區塊模式;其餘保留位元必須依照實作的相容性規則處理。代碼從 9 位元開始,並在字典達到目前寬度的容量時擴展寬度。在區塊模式中,代碼 256 代表 CLEAR:編碼器可以輸出該代碼以捨棄項目,並以初始字母表重新開始。解碼器必須在相同位置重設,然後繼續使用 9 位元代碼。非區塊模式的串流沒有該重設代碼。

代碼寬度轉換規則是 .Z 方言的一部分,因此讀取器應遵循格式指定的時機,而不是從下一個代碼猜測。歷史實作在邊界情況上有所不同;針對目標 compress 實作進行互通性測試是適當的。

相容性與操作 #

LZW 專利曾影響 compress 的部署;相關專利已經到期,但舊有封存檔案與平台特定的解碼器仍構成相容性限制。新資料應使用由通訊協定選定的格式。tar 儲存檔名與中繼資料,而壓縮器會轉換位元組串流,因此 .tar.Z 表示使用 .Z 壓縮的 tar 封存檔。

sh
file backup.tar.Z
uncompress -c backup.tar.Z | tar -tvf -
compress -c source.bin > source.bin.Z
zcat source.bin.Z | sha256sum

.Z 格式沒有可與 gzip 尾端相比的強制端對端校驗和。解碼器可能從截斷或損毀的串流產生看似合理的位元組,因此請保留來源封存檔,並在轉換後驗證外部摘要或已知檔案長度。Gzip 使用 DEFLATE,並在每個成員中記錄 CRC-32 與未壓縮大小,因而對一般檔案傳輸的損毀回報能力更強;但 gzip 與 .Z 並非可互換的串流。

參考資料 #

評論

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