Skip to main content

對抗 ZIP 亂碼檔名大作戰

Technical
Author
Kuan-Yi Li
Table of Contents

ZIP 檔最讓人賭爛的大概就是解壓縮出來的檔名亂碼問題,這在英文系統上面尤其嚴重,只要碰到非 ASCII 的檔名幾乎必死。最近玩政府開放資料,有跨平台的需求,更是被這問題搞到精神耗弱,就順手研究了一下成因及解決方法。

標準怎麼說
#

根據官方 .ZIP File Format Specification 的說法:內容檔名在壓縮檔中預設是以 IBM Code Page 437 編碼的;在 language encoding flag (EFS) 被 set 的時候則以 UTF-8 編碼;不採用這兩種以外的編碼方式!

註:各個內容物(檔案、資料夾或 symbolic link)有獨立的 EFS。

殘酷的現實
#

壓縮軟體的實作,常常把從系統拿到的路徑直接塞進壓縮檔,然而在不同作業系統、不同語系設定之下,軟體拿到的路徑編碼可能是 Big5、GBK、Shift JIS 等等;EFS 也不是檔名用了 UTF-8 的時候就都會被好好地設起來。用沒有依照標準實作的壓縮軟體壓出來的檔案,在解壓縮的時候就有可能用到錯誤的解碼方式去解碼檔名欄位,造成亂碼。

相容性實驗
#

壓縮相容性
軟體環境同語系檔名 範例異語系檔名 範例
編碼EFS編碼EFS
Windows - File Explorer系統編碼No根本不給壓
Windows - 7-Zip系統編碼NoUTF-8Yes
Windows - Bandizip*UTF-8YesUTF-8Yes
OS X - Archive UtilityUTF-8NoUTF-8No
OS X - KekaUTF-8YesUTF-8Yes
OS X - zipUTF-8NoUTF-8No
Linux - zipUTF-8YesUTF-8Yes

嗯……雖然有點慘,但至少沒有設了 EFS 卻又不是 UTF-8 編碼的狀況出現。

解壓縮相容性
軟體環境UTF-8 無 EFS非 UTF-8 或 Code Page 437
運作情形同語系異語系
Windows - File Explorer看不到良好亂碼
Windows - 7-Zip 15.14良好良好亂碼
Windows - 7-Zip 9.20亂碼良好亂碼
Windows - Bandizip*良好良好良好
OS X - Archive Utility良好良好亂碼
OS X - Keka良好亂碼亂碼
OS X - unzip良好亂碼亂碼
Linux - unzip良好亂碼亂碼

解決方法?
#

壓縮
#

環境允許的話盡量避免使用 ZIP 格式。有 non-ASCII 檔名又不得不用的情況下:

  • Windows: Bandizip(記得調整設定,把 ZIP 檔案中使用 Unicode 檔名的功能打開)
  • OS X: Keka
  • Linux: zip

解壓縮
#

  • Windows: Bandizip(但還是有些編碼不支援)
  • Cross-Platform: The Unarchiver - 這個厲害!支援不同編碼、編碼偵測、密碼、有 command line 版本,還跨平台!(Debian, Ubuntu, Fedora, MacPorts, Homebrew
  • Cross-Platform: 找不到現成的好解法,自己用 Java 寫了個陽春的小 command line tool - Onionzip(目前尚不支援加密檔案)

參考資料
#