表紙 / 自作ソフト / 日記 / 宝箱 / サイト情報 / 検索
一般 / 新C言語 / 駄文
一覧 / 本文

IDN: ACE FAQ

Last update: 2003/05/30

(c)2001-2003 seclan. All rights reserved.
Homepage: http://seclan.dll.jp/
E-mail: seclan[ここはアトマークに置き換えてください]dll.jp


Q. IDN って何?

 Internationalized Domain Name の略で ASCII 以外の文字を使用可能にした Domain 名のことです。

Q. ACE って何?

 ASCII Compatible Encoding の略語です。非 ASCII 文字を ASCII 文字互換にする方式のことを言います。この変換方式は Punycode にほぼ決定しました。

Q. ACE の種類についてもう少し詳しく教えて

 次の通りです。

方式表現可能最大値コメント出典

PunycodeUTF32- [RFC3492] Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)
RACEUTF16-draft-ietf-idn-race-02.txt
DUDEUTF16, UTF32-draft-ietf-idn-dude-00.txt


Q. ACE の具体的な変換方式を教えて

 次の通りです。ただし U を UCS または Unicode のコードポイントを表すことにします。また Bxx という表現は左にある U の xx ビット目の値をあらわしています。数字の中の _ は見やすくするために便宜上挿入した記号です。
 また、原則的に、
  • もし文字列が、RFC1035 で定義されている、つまり [A-Za-z0-9-] で示される文字からなっているときは変換せずに、そのまま値を使用する。
  • 文字の正規化、禁止文字の使用など検査済み。
であることとします。

RACE

 Row-based ACE の略語です。DNS への使用を想定した Unicode の Encoding 方式で、UTF-16 表現の変換対象文字列の各文字の上位バイトが全て同一の値であるか、0 または他の単一の値である場合に限って、文字列を圧縮して変換できる機能を持っています。

変換方法

  1. U は UTF-16
    Uu * 256 + Uv = U とし、
    入力文字列を U0 U1 ... Un とするとき、
    
    if({Uu0, Uu1, ... Uun} ∈ {Ubase} || 
      {Uu0, Uu1, ... Uun} ∈ {0, Ubase}){
        //つまり、Uu0, ... Uun 全てが Ubase である、
        //または全てが 0 か Ubase のどれかであるとき
        //なお、全てが 0 の時は、Ubase == 0 と考える
     put(Ubase);
     for(i = 0; i <= n; i++){
      Uu * 256 + Uv = Ui;
      if(Uu == Ubase){
       put(Uv);
       if(Uv == 0xff)	put(0x99);
      } else { //条件 {0, Ubase} のときの Uu == 0 の場合
       put(0xff), put(Uv);
      }
     }
    } else { //圧縮できない
     put(0xd8), put(U0, ..., Un); //出力は上位バイトから
    }
  2. Base32 エンコードをします。Base32 では MSB から 5 bit ずつ区切り、表 "abcdefghijklmnopqrstuvwxyz234567" を使って変換します ("0" と "1" が使われていないことに注意)。もしビットが足りない場合は、最小限 bit 値 0 を追加し変換します。
  3. "bq--" を先頭につけます。(DNS の場合、大文字小文字を区別しないので Bq--, bQ-- などを受け付ける必要があります)

変換例

  • 漢字 (0x226F 0x575B) → 変換 → 
    D8_22_6F_57_5B → 
    1101_1000 0010_0010 0110_1111 0101_0111 0101_1011 → 
    11011 00000 10001 00110 11110 10101 11010 11011 → 
    27 0 17 6 30 21 26 27 → 
    3 a r g 6 v 2 3 → 
    "bq--3arg6v23" (すなわちバイト列 62712D2D3361726736763233)

DUDE

 この方式の特徴は、直前にあらわれた文字コードとの差分だけを記録することにより、文字列を圧縮することにあります。比較的単純な方式です。

変換方法 (for UTF16)

  1. U は UTF-16
    入力文字列を U0 U1 ... Un とするとき、
    
     a16[]="0123456789abcdef";
     b16[]="ghijklmnopqrstuv";
     
     PREV = 0;
     for(i = 0; i < n; i++)
      if(Ui =='-'){put('-');continue;}
      t = PREV ^ Ui ;
      for(j = 0; j < 16; j+=4){
       if((t & (0xfff0 << j)) == 0){
        put(b16[(Ui >> j)&0x0f]);
        for(j -= 4; j >= 0; j -= 4)
         put(a16[(Ui >> j)&0x0f]);
        PREV = Ui;
        break;
       }
      }
     }
  2. "dq--" を先頭につけます。(DNS の場合、大文字小文字を区別しないので Dq--, dQ-- などを受け付ける必要があります)

拡張変換方法 (for UTF32)

  1. U は UTF-32
    入力文字列を U0 U1 ... Un とするとき、
    
     a16[]="0123456789abcdef";
     b16[]="ghijklmnopqrstuv";
     B16[]="GHIJKLMNOPQRSTUV";
     
     PREV = 0;
     for(i = 0; i < n; i++)
      if(Ui > 0x10ffff){error();}
      if(Ui =='-'){put('-');continue;}
      t = PREV ^ Ui ;
      for(j = 0; j < 32; j+=4){
       if((t & (0xfffffff0 << j)) == 0){
        if(j >= 24) { //for 17th plane
         put(isupper(Ui) ? 'W': 'w')); 
        } else {
         put((isupper(Ui) ? B16: b16)[(Ui >> j)&0x0f]);
        }
        for(j -= 4; j >= 0; j -= 4)
         put(a16[(Ui >> j)&0x0f]);
        PREV = Ui;
        break;
       }
      }
     }
  2. "dq--" を先頭につけます。(DNS の場合、大文字小文字を区別しないので Dq--, dQ-- などを受け付ける必要があります)

変換例

  • UTF16: 漢字 (0x226F 0x575B) → 変換 → 
    i26f l75b → 
    "dq--i26fl75b" (すなわちバイト列 64712d2d693236666c373562)
  • UTF32: 漢字 (0x0000226F 0x0000575B) → 変換 → 
    i26f l75b → 
    "dq--i26fl75b" (すなわちバイト列 64712d2d693236666c373562)

Punycode

旧名: AMC-ACE-Z
未稿

表紙 - 著作権 - 注意事項 - リンクについて - 404 エラーについて
(c)2001-2003 seclan. All rights reserved.