【スポンサーリンク】

「Punycode」とは?(国際化ドメイン)

「Punycode」とは?(国際化ドメイン)

Unicodeドメイン名を ASCIIに変換する「Punycode変換」では、先頭に「xn--」という特徴的な文字列が付加され、一見して元の文字列との対応がわかりにくいです。

しかし、これは コンピュータが ASCII文字列に Unicode文字を一つずつくっつけて、元の文字列を復元するための「レシピ」になっています。

実は、一文字ずつ変換する「URLエンコード」と比べて、コンパクトに収まっています。

「Punycode」とは?(国際化ドメイン)

Punycodeは、文字変換だけでなく圧縮も含めた変換です。

\記事が役に立ったらシェアしてね/

この記事では、わかりやすさを重視して説明しています(やや厳密さには欠ける表現もあります)。イメージが掴めたら、より専門的な解説へと進んでください。

【スポンサーリンク】

1. 文字の素とレシピ

Punycode」は、一般に「ピュニコード」と発音されます1

例えば、「ちいLabo」は、
xn--labo-453crg」と変換されます2

Punycodeでは、ASCIIとUnicodeが混在した文字列の場合、
xn--●●-▲▲▲」の形式になります。

「●●」の部分には となるASCII文字列が入り、
「▲▲▲」の部分はUnicodeを付け加える レシピ になっています。

例えば、「1と2345」のように、2文字目にUnicodeが含まれている場合は、「xn--12345-pc4d」というのが、Punycode変換後の文字列です。

逆にいうと、「pc4d」の部分は「2文字目に『と』を追加する」という意味になっているわけです。

punycode文字列
xn--12345-pc4d12345

「pd4d」がどのようにしてできているかは、だいぶややこしいです。
文字変換というよりは、「データ圧縮」のような計算処理だからです。

Bootstringパラメータ

      base         = 36
      tmin         = 1
      tmax         = 26
      skew         = 38
      damp         = 700
      initial_bias = 72
      initial_n    = 128 = 0x80

      code points    digit-values
      ------------   ----------------------
      41..5A (A-Z) =  0 to 25, respectively
      61..7A (a-z) =  0 to 25, respectively
      30..39 (0-9) = 26 to 35, respectively

バイアス適応関数

   function adapt(delta, numpoints, firsttime):
     if firsttime then let delta = delta div damp
     else let delta = delta div 2

     let delta = delta + (delta div numpoints)
     let k = 0

     while delta > ((base - tmin) * tmax) div 2 do begin
       let delta = delta div (base - tmin)
       let k = k + base
     end

     return k + (((base - tmin + 1) * delta) div (delta + skew))

符号化手順

   let n = initial_n
   let delta = 0
   let bias = initial_bias
   let h = b = the number of basic code points in the input

   copy them to the output in order, followed by a delimiter if b > 0
   {if the input contains a non-basic code point < n then fail}

   while h < length(input) do begin
     let m = the minimum {non-basic} code point >= n in the input
     let delta = delta + (m - n) * (h + 1), fail on overflow
     let n = m

     for each code point c in the input (in order) do begin
       if c < n {or c is basic} then increment delta, fail on overflow
       if c == n then begin
         let q = delta

         for k = base to infinity in steps of base do begin
           let t = tmin if k <= bias {+ tmin}, or
                   tmax if k >= bias + tmax, or k - bias otherwise
           if q < t then break
           output the code point for digit t + ((q - t) mod (base - t))
           let q = (q - t) div (base - t)
         end

         output the code point for digit q
         let bias = adapt(delta, h + 1, test h equals b?)
         let delta = 0
         increment h
       end
     end
     increment delta and n
   end

1-1. 一文字を追加する

処理のイメージをつかむために、具体的に少しいじってみます。
例えば、2文字目に追加する文字を「て」や「あ」に変更するコードを見てみます。

punycode文字列
xn--12345-pc4d12345
xn--12345-dc4d12345
xn--12345-643d12345

あるいは、文字を挿入する位置を変えてみます。

punycode文字列
xn--12345-pc4d12345
xn--12345-qc4d12345
xn--12345-sc4d12345

レシピの部分が、ちょっとずつ変わっているのがわかります。

2. 2文字を追加する

2文字目を追加すると、レシピ部分も伸びていきます。

punycode文字列
xn--12345-pc4d12345
xn--12345-pc4duf1と2345
xn--12345-pc4d1f1と2345

コード末尾に2文字ずつ追加されています。

2-1. 2文字目が同じ文字だと簡略

今度は、同じ文字を追加してみます。

punycode文字列
xn--12345-pc4d12345
xn--12345-pc4da1とと2345
xn--12345-pc4dd12345

末尾に増えたのは1文字だけです。

同じ文字だと、「そこから何文字目に追加されるのか」だけの情報で済むので、短く指示できるのです。

2文字目が同じ文字だと簡略

punycodeは、もともとデータ圧縮を考慮して作られているんだね。

2-2. 文字コード表の前の文字だと

ただし、文字コード表の順番が重要です。
例えば、「あ」を追加した場合、コードの外見が大きく変わります。

punycode文字列
xn--12345-pc4d12345
xn--12345-743dvj1と2345

これは「と」よりも「あ」の方がコード表で前にあるので、「あ」を入れるレシピが先になるのです。

先に「あ」を入れたコードと比較するとわかりやすいです。

punycode文字列
xn--12345-743d12345
xn--12345-743dvj12あ345

このように、punycodeでは、使われるUnicodeをコード表の前の文字から順番に、文字列の中に一つ挿入して、文字列を組み立てていきます。

文字が出てきた順でなく、文字コードの順番になっています。

3. レシピの仕組みと圧縮効率

例えば、「12345」というASCIIに「とまと」という文字を挿入した「1と2ま34と5」についてみてみます。

1と2ま34と5」を作るには、
「まず1つ目の『と』を挿入し、
続けて2つ目の『と』を挿入し、
最後に『ま』を挿入する」
というレシピで文字列が完成しています。

punycode文字列
xn--12345-pc4d12345
xn--12345-pc4dd1と2345
xn--12345-pc4dd7o1と234と5

こんなややこしい仕組みですが、実は単純に一文字ずつ変換するより効率的なんです。
実際に一文字ずつ変換する「URLエンコード」と比較してみます。

文字列1と2ま34と5ちいLabo
punycode3xn–12345-pc4dd7oxn–labo-453crg
URLエンコード41%E3%81%A82%E3%81%BE34%E3%81%A85%E3%81%A1%E3%81%84Labo

確かに、Punycodeの方が短い文字数でコード変換できています。

こちらもどうぞ。

迷惑SMSのURLに紛れている変な太字は何なの?【数学用英数字と国際化ドメイン】
迷惑SMSのURLに紛れている変な太字は何なの?【数学用英数字と国際化ドメイン】
迷惑SMSを間違って押してしまったら、わけのわからないアドレスに飛んでしまいました。メッセージをよく見ると、妙に太い文字が含まれていたり、日本語にも下線が引かれています。これは、いったいどこへのリンクなのでしょうか?迷惑SMSのリンクに含まれる 変に太い文字(数学用英数字)や日本語は、「迷惑メールフィルターを逃れるため」の小細工のようです。SMSには、HTMLメールのようなリンクは挿入できず、基本的には表示されているURLがそのままリンク先になります。ただし、「国際化ドメイン...
らくらくスマートフォンで半角カナを入力する 【文字コードの基本】
らくらくスマートフォンで半角カナを入力する 【文字コードの基本】
銀行口座の名義人など、正確な入力が必要な場合は全角カナと半角カナを適切に区別する必要があります。らくらくスマートフォンで半角カナを入力するには、まずひらがなで入力し、「変換」ボタンを押します。すると、変換候補の中に半角カナの文字列もあります。全角カナと半角カナの違いスマートフォンで入力していると、うまくいかないことがあります。例えば、先日あったのが、電気や通信の切替えキャンペーンのキャッシュバックの振込先。「日本語入力ならでは」なのですが、カタカナ(あと数字・英字も)には全角...
[Mac] どうして Control + H で「バックスペース」なの?【ASCIIの制御コード】
[Mac] どうして Control + H で「バックスペース」なの?【ASCIIの制御コード】
Macでは、コントロールキーを押しながら Hキーを押すと「バックスペース」になります。これは、ASCIIの制御コード「BS」を入力するときに、コントロールキーを押しながら0x40足した文字「H」を入力したことに由来しています。macOSのControl + H は bashに由来するmacOSには Controlキーによる、編集作業のショートカットキーがあります。これらの多くは、UNIXプログラムの Emacsや bashのキーバインドに由来します。macOSで Contro...
ギガって どれくらいで なくなるの? 【ギガ使用警告】
1ギガって どれくらいで なくなるの? 【ギガ使用警告】
よく「○○ギガ使用警告」とか表示されると、まだ大丈夫と思っても不安になるんだよね。どれくらいを目安にしたらいい?1ギガ(GB:ギガバイト)のデータ通信量の目安を見てみましょう。1GBのデータ通信量動画のデータデータ通信で、まず気をつけたいのは、動画データです。動画の時間あたりのデータ量は、画質がよいほど大きくなります。例えば、Youtube動画の場合は 約90分で1GBになります(通常画質(720p)。動画の画質にもよるので一概には言えませんが、一つの目安として、覚えておくと...

(補足)

  1. JPRS用語辞典|Punycode(ピュニコード)
  2. 日本語JPドメイン名のPunycode変換・逆変換 – 日本語.jp
  3. 日本語JPドメイン名のPunycode変換・逆変換 – 日本語.jp
  4. URLエンコード・デコード|日本語URLをサクッと変換 | すぐに使える便利なWEBツール | Tech-Unlimited
QRコードを読み込むと、関連記事を確認できます。

「Punycode」とは?(国際化ドメイン)
【スポンサーリンク】
タイトルとURLをコピーしました