DOBON.NET

ホスト名(ドメイン名)をPunycodeに変換(エンコード、デコード)する

ここでは、ドメイン名やホスト名をPunycode(ピュニコード)に変換(エンコード)する方法と、Punycodeから元の文字列に戻す(デコード)する方法を紹介します。

IdnMapping.GetAscii、GetUnicodeメソッドを使用する

IdnMapping.GetAsciiメソッドを使ってPunycodeにエンコードすることができます。また、IdnMapping.GetUnicodeメソッドを使ってPunycodeからデコードすることができます。これらのメソッドは、.NET Framework 2.0から使用できます。

VB.NET
コードを隠すコードを選択
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
C#
コードを隠すコードを選択
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

Uri.DnsSafeHostプロパティを使用する

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解析が無効の時はRFC2396RFC2732に従った動作ですが、有効にするとRFC3986RFC3987に従った動作になります。

IDN解析が有効になれば、例えば次のようにして、DnsSafeHostプロパティでPunycodeに変換されたホスト名を取得することができます。

VB.NET
コードを隠すコードを選択
'-----------------------------------------------
'ホスト名を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
C#
コードを隠すコードを選択
//-----------------------------------------------
//ホスト名を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

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • .NET Tipsをご利用いただく際は、注意事項をお守りください。
共有する

この記事への評価

この記事へのコメント

この記事に関するコメントを投稿するには、下のボタンをクリックしてください。投稿フォームへ移動します。通常のご質問、ご意見等は掲示板へご投稿ください。