Punycode
Unicode |
---|
文字符号化スキーム |
UTF-7 |
UTF-8 |
CESU-8 |
UTF-16 |
UTF-32 |
UTF-EBCDIC |
SCSU |
Punycode (IDN/IDNA) |
GB 18030 |
その他 |
UCS |
マッピング |
書字方向 |
BOM |
漢字統合 |
UnicodeとHTML |
Unicodeと電子メール |
Unicodeフォント |
Punycode(ピュニコード、プニコード)とは、国際化ドメイン名で使われる文字符号化方式で、RFC 3492 で定義されている。Unicode で書かれた文字列をDNS内の制限された文字コード空間でも使えるようにするための方式で、ユーザーエージェントの実装に依存する。
概要
ドメイン名として Punycode を使用する際は、ピリオド(.
)で区切られたドメイン名の階層レベルごとにプレフィックスとして「xn--
」を使用し、エンコードされた文字列を続ける。大文字と小文字は区別されない。
可読なドメイン名 | Punycodeでのドメイン名 |
---|---|
ドメイン名例.jp |
xn--eckwd4c7cu47r2wf.jp
|
ウィキペディア.ドメイン名例.jp |
xn--cckbak0byl6e.xn--eckwd4c7cu47r2wf.jp
|
例え.テスト |
xn--r8jz45g.xn--zckzah
|
エンコーディング手順
この節では Punycode のエンコーディング手順を、「bücher
」[1]がどのようにして「bcher-kva
」と変換されるかを例にとって説明する。
ASCII文字の分離
最初に入力文字列中にあるすべての基本文字(ASCII)を残し、基本文字以外の文字は飛ばす。基本文字以外の文字がある場合は、最後に区切り文字(ハイフン)を追加する。
入力文字列 | 処理後 |
---|---|
bücher |
bcher-
|
日本Japan |
Japan-
|
非ASCII文字の挿入をコード番号としてエンコード
次のエンコーディング手順を理解するために、先にデコーダの動作を理解する必要がある。デコーダは2つの状態変数 i と n を持つオートマトンである。 i は文字列への挿入位置のインデックスで、その範囲は0(これは文字列の先頭への挿入を表す)から現在の文字列の長さ(文字列の末尾への挿入を表す)である。nは挿入されるべき文字のコードポイントである。
i は0から始まり、n は128(非ASCII文字の最初のコードポイント)から始まる。状態遷移は単調であり、遷移すると i が1だけ増加する。ただし i がすでに最大値の場合は n を1増加し、i は0に戻る。各状態遷移の際、nで表されるコードポイントを文字列に挿入するか、挿入をスキップする。
デコーダが文字を挿入する前に、スキップすべき挿入可能位置がいくつあるかを数値化したものがエンコーダによって生成されるコード番号である。"ü"のコードポイントは252である。よって ü の字を文字列の1文字目の後ろに挿入するには、"bcher"の中に6か所ある挿入ポイントに、üより前にある124の非ASCII文字が挿入されるのをスキップし、さらに0文字目(つまり文字列の先頭)にüが挿入されるのをスキップする必要がある。したがって、デコーダには必要な1文字を挿入するために、(6 × 124) + 1 = 745 の挿入可能位置をスキップするよう伝える必要がある。
コード番号をASCII文字列として再変換
Punycodeはこのコード番号を表すためにリトルエンディアンの一般化可変長整数を使用する。例としてコード番号745を「kva」と表す方法を示す。
一般化可変長整数では、各々の桁に異なる閾値を設け、これより小さい数字の表れる桁を最大桁とすることで数字列の区切りを決める。Punycodeで用いられるリトルエンディアンの場合、小さい桁から表記されるため、先読みなしで任意の桁数の数字を表記できる。
Punycodeの場合は各桁に使える数字として36種の文字を使用する。アルファベット(大文字小文字を区別しない)の'a'から'z'が0から25を表し、数字の'0'から'9'が26から35を表す。したがって「kva」は「10 21 0」を表す。ここで閾値は(1 1 26)であるとする。最初の桁(「k」あるいは「10」)の重みづけは1である。1桁目は1~35までの範囲の値をとるため、2桁目の重みは35となる。2桁目は同様に1~35の範囲の値をとるため、3桁目の重みは35×35=1225である。また、3桁目の値「0」は3桁目の閾値は26よりも小さいため、ここで数字列は終了であることがわかる。したがって「kva」は10 × 1 + 21 × 35 + 0 × 1225 = 745を表していることがわかる。
各桁の重みw(j)および閾値t(j)の値は以下の式で計算される。
(ただしt(j)はt_min以下ならt_min、t_max以上ならt_max)
2つ目の文字列を挿入する際にはさらにエンコードされたコード番号を追加すればよいが、挿入の度にbiasの値が調節され、各桁の重みと閾値が変わることに注意する必要がある。biasの値が変わらない範囲であれば単純に追加するだけでよい。例えば"bücher"に2つ目の特殊文字を挿入しようとすると、最初の挿入可能位置は"büücher"で、コード"bcher-kvaa"となる。次の挿入可能位置は"bücüher"で"bcher-kvab"となる。同様に続き"bücherü"は"bcher-kvae"となり、次に来るのは"ýbücher"で"bcher-kvaf"である。
脚注
関連項目
外部サイト
- RFC 3492
- Punycode encoding and decoding
- Punycode converter
- Online Punycode/IDN Decoder/Encoder
- GNU IDN Library—Libidn
- ICU IDNA Demonstration An online demonstration of how ICU performs IDN operations
- Punycode for Domains Convert Unicode to Punycode
- List of TLDs considered by the Mozilla developers to have an effective anti-spoofing policy for name registration
- IDN and Punycode in IE7
- Punycode converter for Korean
- 日本語JPドメイン名のPunycode変換・逆変換 - 日本語.jp