| 類別 | 定義 | 典型格式 | 適用場景 |
|---|---|---|---|
| 無損壓縮 | 解壓後位元級完全還原 | ZIP, GZIP, PNG, GIF, FLAC | 程式碼、文件、資料庫、無線傳輸 |
| 有損壓縮 | 犧牲不可察覺資訊換取高壓縮比 | JPEG, MP3, H.264, WebP | 圖片、音訊、影片、串流媒體 |
本文聚焦 通用無損壓縮,核心演算法演進:霍夫曼編碼 → LZ77 → LZ78 → LZW → DEFLATE (LZ77+霍夫曼)。
出現機率高的符號分配短碼,低機率分配長碼;前綴碼 保證無歧義解碼 (無碼字是另一碼字前綴)。
符號: A B C D
頻率: 12 3 4 5
霍夫曼樹:
root(24)
/ \
A(12) @(12)
/ \
D(5) @(7)
/ \
C(4) B(3)
編碼: A=0, D=10, C=110, B=111
總位元: 12*1 + 5*2 + 4*3 + 3*3 = 43 bits
固定 2-bit 編碼需 48 bits → 壓縮 10%
字典 = 已處理過的資料本身 (滑動視窗),無需外部字典。尋找「當前位置前方視窗內」最長匹配,輸出 <相對位移, 匹配長度>;找不到則輸出原始字面值。
輸入: AABAABAAB
視窗大小: 4096 (12-bit 位移), 最大匹配長 16 (4-bit 長度)
步驟 1: 輸入 AABAABAAB, 字典=空 → 輸出 'A'
步驟 2: 輸入 ABAABAAB, 字典=A → 輸出 'A'
步驟 3: 輸入 BAABAAB, 字典=AA → 找到 'A' 位移 1 長 1 → 輸出 <0,1>
步驟 4: 輸入 AABAAB, 字典=AAB → 輸出 'B'
步驟 5: 輸入 ABAAB, 字典=AABAAB → 找到 'AAB' 位移 3 長 3 → 輸出 <0,3>
... 以此類推
關鍵點:
- 最小匹配長度通常設 3 (因 <位移,長度> 本身佔 2 bytes,<3 不划算)
- 位移 12-bit → 4KB 視窗;長度 4-bit → 最大 16 bytes
- 解壓時需 1-bit 標誌區分「字面值」vs「匹配碼」
LZ77 輸出 <位移,長度>,LZW 改為 字典索引:
W。W 的索引,將 W + 下一字元 加入字典。GIF、Unix compress、早期 ZIP 皆採 LZW 變體。
DEFLATE = LZ77 (滑動視窗 32KB) + 霍夫曼編碼
zlib / libdeflate / Java java.util.zip 皆為 DEFLATE 實作。
| 演算法 | 壓縮速度 | 解壓速度 | 壓縮率 (文字) | 記憶體需求 |
|---|---|---|---|---|
| 霍夫曼 (靜態) | 快 | 極快 | ~60% | 極低 |
| LZ77 (4KB 視窗) | 中 | 快 | ~50% | 低 (4KB) |
| LZW | 中 | 快 | ~45% | 中 (字典表) |
| DEFLATE (zlib level 6) | 中 | 快 | ~35% | 中 (32KB 視窗+樹) |
| LZMA (7z/xz) | 慢 | 中 | ~25% | 高 (MB 級字典) |
GZIPInputStream 解壓 (MIDP 2.0+ 支援)。理解「編碼優化 (霍夫曼) + 字典替換 (LZ77/LZW)」雙引擎架構,即可看透 ZIP/GZIP/PNG/DEFLATE 等主流格式本質。在資源受限環境 (J2ME、嵌入式),選擇「定長視窗 LZ77 + 位元打包」自製輕量壓縮,往往比移植通用庫更務實。