utf-8(NFC)とutf-8-mac(NFD)における日本語ファイル名

こんにちわ。
昨晩からハマっているタイチです。
さて、いつものように今回は何にハマっているかというと…

最近ではwebdavを使用して、ファイル共有を行うことが多くなってきてますが、
昔はMacとWindowsのファイ共有というのは、ご法度でした。
しかし最近では、MacとWindowsのファイル共有を行うことが
必要不可欠になってきています。

そんな中、各々の環境でファイルを保存する時は、
日本語の2byte文字を使用することが多くなってきており、
それに対応すべく、各OSではどのように日本語処理をしようか、
格闘しているわけです。
今回のハマりポイントは、
WinとMacの文字コードUTF-8における解釈の微妙な違いです。

これは、WindowsはUTF-8でもNFCというnormalizationをしていない形、
Macの場合は厳密にいうとUTF-8-MACというnormalizationをしたNFDという
各々微妙に違うわけで、
簡単にわかる方法としては、windows上のエクスプローラー上では分かりずらいので、
コマンドラインで行うのが分かりやすいと思います。

コマンドプロンプトを表示して、該当のディレクトリに移動して、dirコマンドを叩くと、
MacとWinでファイル名が実際には異なることが分かるはずです。
例えば、windows上で
【パパのアルバム.xls】
というファイルがあるとしたら、macで作成した(ipadでも同じ)ファイルを同じように名前を付けて、
windows上にあげたとした場合、
【ハ゜ハ゜のアルハ゛ム.xls】「ハ」と半濁点の「゜」が分解されて管理してることになります。

さらに、ここでややこしいのは、Windows上のエクスプローラー上で見ると、
この分解された形が優しいのか優しくないのか、
 「パ」
と一文字で変換されて表示されてしまいます。
人間が見るわけなので、それでよいのですが、
この人間が見た形が「一文字で見えるよ」と勘違いを起こして、
どこで問題が起きているのか、分からなくなるわけです。
では、問題に戻って、どう処理すればよいのか、ですが。
問題は色々とあります。
私がいくつか行ってみた・調べた内容ですが、

  1. phpで変換してみる
    そもそも、phpはutf-8-macの文字コードは認識しない
  2. phpの拡張intlのclass normalizerを使用してみる
    これも今回はWindows上のphpで行ってみたのですが、「?」文字で変換されてしまい、ダメ…
  3. asp.netで変換してみる
    これは、NFC→NFDに変換するクラスがあるようですが、環境になく試せず…
  4. vbsで変換してみる
    これもできるのか確認してみたが、そんなメソッドやプロパティはなく…
  5. cscript(コマンドプロンプト的なもの)で、dirコマンドなどを駆使してみる
    こちらも文字変換しようにもmacの「゜」がwindows上で判断ができない模様…

このような形で色々と試してみたのですが、
サーバー側で何かしら処理を行うのは、フォーム上で2を行うのが
せいぜいなのかなと考えています。
ならば、Mac側のアプリで処理するしかないということになるわけです。
そこでmac側のアプリであるxcodeでこの変換処理、
すなわち、NFC→NFDでファイル名を変更してPUTするということになりそうです。
(参考URL参照)

xcode上で

// NFD
– (NSString *)decomposedStringWithCanonicalMapping

// NFKD
– (NSString *)decomposedStringWithCompatibilityMapping

// NFC
– (NSString *)precomposedStringWithCanonicalMapping

// NFKC
– (NSString *)precomposedStringWithCompatibilityMapping

という文字列変換のメソッドを利用するのが良いかと考えています。

※xcodeを使用したアプリは、今回私の方で制作しているわけではないので、
おそらく、上記を考慮したプログラムになったおかげで、
ファイル名の問題はなくなりました。

【参考URL】http://akisute.com/2010/05/utf-8-normalize.html

結論から行くと、
そもそも2byte文字を使わないようにした方が良い
というのが本音ですね…