【スポンサーリンク】

「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がそのままリンク先になります。ただし、「国際化ド...
らくらくスマートフォンで半角カナを入力する 【文字コードの基本】
らくらくスマートフォンで半角カナを入力する 【文字コードの基本】
スマートフォンで入力していると、うまくいかないことがあります。 例えば、先日あったのが、電気や通信の切替えキャンペーンのキャッシュバック。 振込先の銀行口座の名義人の入力など、慣れないと難しいものです。 今回は、「全角カナ」と「半角カナ」について説明します。 全角カナと半角カナの違い 日本語入力ならではなのですが、カタカナ(あと数字・英字も)には全角と半角の2種類の文字あります。 2種類のカタカナ文字 全角カナ半角カナ 「全角カナ」と「半角カナ」は、見た目にそんな違いがありま...
[Mac] どうして Control + H で「バックスペース」なの?【ASCIIの制御コード】
[Mac] どうして Control + H で「バックスペース」なの?【ASCIIの制御コード】
Macでは、コントロールキーを押しながら Hキーを押すと「バックスペース」になります。 これは、ASCIIの制御コード「BS」を入力するときに、コントロールキーを押しながら0x40足した文字「H」を入力したことに由来しています。 macOSのControl + H は bashに由来する macOSには Controlキーによる、編集作業のショートカットキーがあります。これらの多くは、UNIXプログラムの Emacsや bashのキーバインドに由来します。 macOSで Co...
ギガって どれくらいで なくなるの? 【ギガ使用警告】
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をコピーしました