国際化ドメイン名 ( IDN ) について
国際化ドメイン名を使うと、ドメイン名にアルファベットや数字だけでなく日本語を含む様々な文字が利用出来るようになる。自分の書いたコードを、これに対応させるにはどうすればいいか?*1これは、ドメイン名から IP アドレスを得る話なので、名前解決の話である。名前解決といえば、まず思い浮かぶのは getaddrinfo() だろう。
Linux の場合、glibc 2.3.4 からは、AI_IDN というフラグを加えてやることで対応できる。Mac OS X や Windows ではそういったフラグは見当たらない。Windows では、IdnToAscii() によって得られた結果を getaddrinfo() に渡すことで国際化ドメイン名に対して名前解決ができるようになる。
では Mac OS X ではどうしているのだろうか、と思い調べてみると、何らかの外部ライブラリを利用している場合があるようだ。例えば、Mac OS X 専用の Twitter クライアントとして有な夜フクロウは、VeriSign が提供している IDN Library を使っているらしい。他にも、GNU が提供しているものや、JPNIC が提供しているものなど様々なライブラリがある。
- Software for International Domain Names - IDN Software Development Kit - Verisign
- GNU IDN Library - Libidn - GNU Project - Free Software Foundation
- 当然 GPL
- idnkit download
- おそらく BSD ライセンス
国際化ドメイン名は結構新しい仕組みなので、プラットフォームごとに対処がばらばらで中々に厄介である。Linux がとった対応方法が一番シンプルに見える。
では、上記ライブラリを使わずに国際化ドメイン名の名前解決をやるにはどうすればいいだろうか?それには、国際化ドメイン名とは何ぞやというのを知る必要がある。
- RFC 3490 - Internationalizing Domain Names in Applications (IDNA)
- RFC 3491 - Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)
- RFC 3492 - Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)
大雑把にまとめるとこのような感じになる。
- 国際化ドメイン名に含まれる文字列をそのまま扱うのは既存資産の対応という意味で厳しい
- だったら国際化ドメイン名を既存資産が扱える文字列に変換してしまおう
- ベースとなる文字コードは UTF-32 でいいだろう
- 変換方式は Punycode と名付けよう
- 実際に国際化ドメイン名を変換するときは、ドメイン名をラベルごとに Punycode で変換し、「xn--」というプレフィクスをつけよう
ここで少し面倒なのが、Unicode のサポートである。が、Linux や Mac OS X ならデフォルトで UTF-8、Windows なら UTF-16 がサポートされている。そして、Unicode 同士の変換はそんなに複雑ではないのだ。*2
というわけで、実装するなら以下のような処理が必要になる。
- UTF-8,UTF-16 を UTF-32 に変換する処理
- LE 限定なら、C で書いても 200 行足らずで書ける
- Punycode 変換する処理
- RFC にのっているコードを参考にして実装できる
- C で書いても 200 行足らずで書ける
- ドメイン名をラベルで分割する処理
- ラベルを Punycode で変換する処理
- Punycode で変換したラベルで結合する処理
- 必要に応じて「xn--」というプレフィクスをつける処理
試しに書いたコードでは、C で一から書いて全部で 600 行くらいになった。C だとやっぱり長くなるな。JavaScript で書かれた実装なんかもあるので、興味のある方はどうぞ。
IDN はそんなに怖くない、ということで。お粗末。