對抗 ZIP 亂碼檔名大作戰

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 系統編碼 No UTF-8 Yes
Windows – Bandizip* UTF-8 Yes UTF-8 Yes
OS X – Archive Utility UTF-8 No UTF-8 No
OS X – Keka UTF-8 Yes UTF-8 Yes
OS X – zip UTF-8 No UTF-8 No
Linux – zip UTF-8 Yes UTF-8 Yes

嗯……雖然有點慘,但至少沒有設了 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(目前尚不支援加密檔案)

參考資料

Posted in Technical.

6 Comments

    • unzip 的這個功能並不是每個 distro 都有,像是 Debian 就沒上 alt-iconv-utf8 這個 patch。

Leave a Reply

Your email address will not be published. Required fields are marked *

Captcha loading...