日本の商習慣として未だに残っているのが「ファイルをまとめてzipで渡す」というやつである。数年前までビジネスで使われるコンピュータはWindowsがデファクトスタンダードだったので、zipファイルを作成するのも、展開するのも同じソフトウェアを使っていたから特に問題が起きることはなかった。古き良き時代であるが、近年ではMacOSも普及し、ビジネスでファイルをやりとりするのに使えるようになってきた。複数のOSが併用されるようになったが、相変わらずファイルのやりとりはzipで行われるという商習慣の形として残った。
私の意見はそもそもそういう商習慣を撤廃するべきだということに尽きるのだが、家族を養う手前既存の商習慣に従わなければならない。そしてここ数年は、仕事でもMacOSを使っている。MacOSとWindowsの間でファイルをやり取りするときの問題その1は暗号化zipである。問題その2は表題にあるとおり、日本語のファイル名を持つファイルが文字化けしてしまい、意味のあるファイル名だったときにビジネス上のコミュニケーションに支障が出てしまうことである。
もしビジネスでなかったらそんなファイルはすぐにrmしてしまうべきであるが、ここまで読んで頂いたということは、読者諸賢もこの問題でお困りのことであろうから、私の調べたことがいくらかでもお役に立てば幸いである。
TL;DR
なぜファイル名が文字化けするのか
Windowsのファイルシステムでは、基本的に日本語のファイル名はcp932でエンコードされている。後方互換姓のためこれが今後も変わることはないと思われる。また、最新のWindowsでもUTF-8などでファイル名をエンコードしてzipアーカイブを作ることはできないようだ。Explororのメニューからアーカイブを作るとcp932でファイル名もzipアーカイブ内に保存されてしまう。7zipなどのサードパーティのアプリケーションを使えば、Unicodeでアーカイブすることができる。
また、ZIPの仕様では、ファイル名のエンコーディングに関する指定はAppendix Dに 「歴史的にIBMコードページ437しかサポートしていなかった」と書かれている。CP437とは何かというと、いわゆるASCIIのセットにラテン文字を追加したもののようで、当然日本語の文字が入っているわけではない。CP437はDOSのOEMコードセットというらしい。ここでいうDOSはMS DOSのことであるから、WindowsにIBMコードページが追加されていき、日本語版Windowsのファイルシステムの標準文字コードとして、また、そこから作られるZIPアーカイブでCP932が採用されることのは歴史的な経緯としては自然なようだ。
一方、MacOSのファイルシステムは、 APFS でも HFS+ では、基本的にUTF-8でファイル名がエンコードされている。
APFS has case-sensitive and case-insensitive variants. The case-insensitive variant of APFS is normalization-preserving, but not normalization-sensitive. The case-sensitive variant of APFS is both normalization-preserving and normalization-sensitive. Filenames in APFS are encoded in UTF-8 and aren’t normalized.
HFS+, by comparison, is not normalization-preserving. Filenames in HFS+ are normalized according to Unicode 3.2 Normalization Form D, excluding substituting characters in the ranges U+2000–U+2FFF, U+F900–U+FAFF, and U+2F800–U+2FAFF.
Finderのメニューで展開しても、 `/usr/bin/unzip` を利用しても、基本的には zip アーカイブ内のファイル名のところにあるバイト列をそのままファイル名として展開する。したがって、UTF-8しか対応していないHFS+のファイル名に、CP932でエンコードされた文字列が保存されてしまう。Finderを始めとした各種アプリケーションはHFS+の仕様に従ってUTF-8だと思ってCP932のファイル名を表示するので、よくわからない化けたファイル名が表示されることになる。
まとめると、WindowsではCP932でZIPを作る、ZIPは慣習的にCP932やCPxxxでのファイル名のエンコードを許容している、MacOSはそんなことしらないでUTF-8として扱う、のコンボで、結果的にこういうことになるようだ。
ワークアラウンド、今後の期待
Macに含まれているInfo-ZIPが6.00であるから、それが最新版にアップデートされれば解決するか?という答えは半分正解で、半分不正解だ。まず、このCP932対応が含まれているバージョンがまだ正式にリリースされておらず、ベータ版が 2010年にリリースされて以来ずっと放置されている。どうもやる気がないないらしい。スレも立っているがやはり放置されているので期待できない。こんなに必要とされているソフトウェアなのにリリースされないとは、OSSはさすがにかくあるべしといった感がある。
もし万が一これがリリースされたとして、MacPortsに入るのは早いだろうが、MacOSのリリースにバンドルされるのはいつのことになるやら知れたものではない。現にPythonは2.7だし、Rubyだって今みたら未だに2.0.0である。
つまり公式は期待できないので、ZIPファイルを受け取るMacOS側がどうするべきかというと、
- GUIでもいい人はUnarchiverを自分でインストール
- GUIでもよくてApp Storeから入れたい人はZIPANGをポチポチと入れる
- デファクトのCUIツールを使いたい人は unzip のベータ版 (unzip610b.zip) を自分でインストール
- デファクトじゃなくてもいい人は unar を自分でインストール
くらいが関の山である。
次点で期待できるものとして、Goで書かれた mholt/archiver にパッチを当てるというものがある。 x/text/encoding/japanese を使うとよさそう。有志に期待している。もしGoを書きたくなったら僕がやるかもしれない。
ZIPアーカイブを作る側、Windows側でできることがあるとすれば、 UTF-8 によるエンコードはサポートされていないようなので、もし相手がMacユーザーだと分かっている場合は、予め 7zip 等のサードパーティツールを使ってUTF-8でZIPアーカイブを作成するのがよさそうである。
おまけ、問題3、逆: Macで作ったzipアーカイブが中に日本語のファイル名を持つときにWindowsでファイル名を文字化けさせずに展開できるか
UTF-8のファイル名が保存されたものは Windows 7のあるバージョンからできるようになっている。これは、ZIPの仕様に、ファイル名がUTF-8でエンコードされていることを示すフラグがあり、それに従ってファイル名を変換しているようだ。
4.4.4 general purpose bit flag: (2 bytes) ...(snip)... Bit 11: Language encoding flag (EFS). If this bit is set, the filename and comment fields for this file MUST be encoded using UTF-8. (see APPENDIX D)
しかしながら、 MacOS のFinderでのアーカイバはそのフラグをつけずに UTF-8 でエンコードしてしまうらしい。
一方MacOSに含まれている "/usr/bin/zip" コマンドは Info-ZIP の 3.0 なので問題はなさそうだ *1 。リリースノートに "Unicode (UTF-8) filename and (partial) comment support" と書かれている。
参考
- ZIP中のファイル名の文字化け - @tmtms のメモ
- 日本語を含むZIPファイルを文字化けせず解凍する方法 - Qiita
- Technical Note TN1150: HFS Plus Volume Format
- Technical Note TN1150: HFS Plus Volume Format
File and folder names on HFS Plus consist of up to 255 Unicode characters with a preceding 16-bit length, defined by the type HFSUniStr255.
- Japanese characters in file names are displayed as garbled text after you decompress a .zip file in Windows 7 or in Windows Server 2008 R2
- Mac OS HFS+ におけるファイル名文字コード - 彷徨えるフジワラ
- ZIP 書庫ファイルに格納されたファイルの名前の文字化け | ECCS Tutor's page
- IBM Knowledge Center CP437とCP932が同じ表にある
- 文字コードの話
- たとえばArch Linuxだと iconv のパッチを当てたものが公式レポジトリに含まれているようだ
- Thanks to Moriyoshi for example zip file and solid review, to Wozozo for Unarchive
*1:Finderはこのツールを使っていないということか…?!