ここでは、ドメイン名やホスト名をPunycode(ピュニコード)に変換(エンコード)する方法と、Punycodeから元の文字列に戻す(デコード)する方法を紹介します。
IdnMapping.GetAsciiメソッドを使ってPunycodeにエンコードすることができます。また、IdnMapping.GetUnicodeメソッドを使ってPunycodeからデコードすることができます。これらのメソッドは、.NET Framework 2.0から使用できます。
Dim hostName As String = "www.日本.com" 'IdnMappingオブジェクトを作成する Dim im As New System.Globalization.IdnMapping() 'punycodeにエンコードする Dim punycode As String = im.GetAscii(hostName) '結果を表示する Console.WriteLine(punycode) 'www.xn--wgv71a.com 'punycodeをデコードする Dim newName As String = im.GetUnicode(punycode) '結果を表示する Console.WriteLine(newName) 'www.日本.com
string hostName = "www.日本.com"; //IdnMappingオブジェクトを作成する System.Globalization.IdnMapping im = new System.Globalization.IdnMapping(); //punycodeにエンコードする string punycode = im.GetAscii(hostName); //結果を表示する Console.WriteLine(punycode); //www.xn--wgv71a.com //punycodeをデコードする string newName = im.GetUnicode(punycode); //結果を表示する Console.WriteLine(newName); //www.日本.com
URLを指定してUriオブジェクトを作成して、Uri.DnsSafeHostプロパティを調べれば、Punycodeにエンコードされたホスト名が分かります。また、Uri.Hostプロパティを調べれば、Punycodeにエンコードされていないホスト名を知ることができます。
ただしこの方法は、国際化ドメイン名(IDN)解析が有効になっていないと使えません。IDN(および、後述するIRI)解析は.NET Framework 2.0 SP1からサポートされていますので、それ以前の.NET Frameworkではできません。
IDN解析を有効にする方法は、MSDNの「<idn> 要素 (Uri 設定)」(あるいは、「Uri.DnsSafeHost プロパティ」)で説明されています。これによると、app.config(または、machine.config)ファイルに次のような内容を追加します。
補足:app.configファイルの作成方法については、「「アプリケーション構成ファイル」を使用して設定を読み込む」をご覧ください。
<configuration> <configSections> <section name="uri" type="System.Configuration.UriSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> </configSections> <uri> <idn enabled="All"/> <iriParsing enabled="true"/> </uri> </configuration>
.NET Framework 4.0のmachine.configには「<section name="uri" ...」の記述がデフォルトでありましたので、.NET Framework 4.0以降であれば、<uri>要素の追加だけで十分だと思われます。また、上の例では<iriParsing>要素によって国際化リソース識別子(IRI)解析も有効にしていますが、もしDnsSafeHostプロパティでPunycodeのエンコード、デコードが行われるだけで良いのであれば、<idn>要素だけで十分です。ただ、両方有効にすべきでしょう。
IRIとIDNの解析を有効にすると、DnsSafeHostプロパティだけでなく、Uriクラスの他のメンバの動作にも影響を及ぼします。Uriクラスは、IRI解析が無効の時はRFC2396とRFC2732に従った動作ですが、有効にするとRFC3986とRFC3987に従った動作になります。
IDN解析が有効になれば、例えば次のようにして、DnsSafeHostプロパティでPunycodeに変換されたホスト名を取得することができます。
'----------------------------------------------- 'ホスト名をPunycodeにエンコードする '----------------------------------------------- 'Uriオブジェクトを作成する Dim u1 As New Uri("http://日本.com/") 'Punycodeにエンコードされたホスト名を取得する Console.WriteLine(u1.DnsSafeHost) 'xn--wgv71a.com 'Punycodeに変換されていないホスト名を取得する Console.WriteLine(u1.Host) '日本.com '----------------------------------------------- 'ホスト名をPunycodeからデコードする '----------------------------------------------- 'Uriオブジェクトを作成する Dim u2 As New Uri("http://xn--wgv71a.com/") 'Punycodeにエンコードされたままのホスト名を取得する Console.WriteLine(u2.DnsSafeHost) 'xn--wgv71a.com 'Punycodeからデコードされたホスト名を取得する Console.WriteLine(u2.Host) '日本.com
//----------------------------------------------- //ホスト名をPunycodeにエンコードする //----------------------------------------------- //Uriオブジェクトを作成する Uri u1 = new Uri("http://日本.com/"); //Punycodeにエンコードされたホスト名を取得する Console.WriteLine(u1.DnsSafeHost); //xn--wgv71a.com //Punycodeに変換されていないホスト名を取得する Console.WriteLine(u1.Host); //日本.com //----------------------------------------------- //ホスト名をPunycodeからデコードする //----------------------------------------------- //Uriオブジェクトを作成する Uri u2 = new Uri("http://xn--wgv71a.com/"); //Punycodeにエンコードされたままのホスト名を取得する Console.WriteLine(u2.DnsSafeHost); //xn--wgv71a.com //Punycodeからデコードされたホスト名を取得する Console.WriteLine(u2.Host); //日本.com
注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。