UCS と Unicode

 

 

  目次  
【1】 UCS と Unicode の概要と2つの違い
【2】 UCS-4 / UTF-32
【3】 UTF-8
【4】 UCS-2 / UTF-16
【5】 UTF-7
【A】 UTF-9

 

 

 

UCS と Unicode の概要と2つの違い

 

UCS ( Universal Multiple-Octet Coded Character Set ) は全ての言語の 文字を一つの ( 統一された ) コードに割り当てるものです。 コードテーブルは 0 〜 0x7FFFFFFF と、約21億文字分 有ります。 1文字あたり4バイト使用するため UCS-4 とも呼ばれます。

 

Unicode は UCS の 0 〜 0x10FFFF ( 約 111 万文字 ) の部分をいいます。
使います、と書きましたが実際は UCS と Unicode は策定しているグループが異なります。 UCS を策定しているグループが下位部分を採用したことから互換性が発生し、 サブセット(部分集合)レベルでは同一とみなせるのが現状です。

 

UCS-4 の範囲では UCS-4 ( UTF-32 とも呼ばれます ) UTF-8 の2種類のコーディングが可能です。 また、標準では有りませんが、 UTF-9 という コーディングもあります。
Unicode の定義範囲に限ればこれに加えて UTF-16UTF-7 の2種類が使えます。 ( UCS-4 を使うことは無いと思いますが‥‥ )
Unicode の定義範囲内のうち、 0 〜 0xFFFF だけの ( つまり当初の Unicode の定義 ) 範囲を UTF-16 で表現したものを UCS-2 と呼びます。 通常 Unicode と言ったらこのエンコーディングを指します。

 

Unicode についてもっと詳しく知りたい方はオフィシャルページ http://www.unicode.org/ や各種変換表がダウンロードできる ftp サーバ ftp://ftp.unicode.org/Public/ へどうぞ。
機種依存文字の変換表は今田が作ったものが Shift-JIS のページにあります。
opengroup のページ には Unicode.org とは違う変換表があります. 同サイトには Unicode とユーザ定義文字・ベンダ定義文字に関する問題点と解決策 なるページがあります.

 

 


 
 
 

UCS-4 / UTF-32

 

UCS-4 のコード番号そのままのコーディングで、1文字に付き4バイト使用します。 UTF-32 は UNICODE のコーディングですが UCS-4 と同じとみても、問題はないでしょう。 特徴としては1文字が4バイトに固定されていることで、唯一の固定長 のコーディングといえます。( UTF-16 は 0x10000 〜 0x10FFFF を 表示する場合 16 ビット×2となり、固定長といえません。) このコーディングではバイトオーダーを指定することが出来ます。 UCS では 0x0000FEFF ("BYTE ORDER MARK" or "BOM") がバイトオーダー指定文字として定義されています。 なお,0x0000FEFF は "ZERO WIDTH NON-BREAKING SPACE" ( 幅0でこの文字の後にブレイク ( 画面に収まりきらない場合に改行 文字無しに改行する場合の改行を言う ) なしのスペース ) という意味 としても定義されています。

 

例を挙げます。「今日は」という文字列をコーディングする場合を 考えます。コード番号は 「今」は 0x00004ECA 、 「日」は 0x000065E5 「は」は 0x0000306F です。 バイトオーダー別文字列の出力結果を次に示します。 結果にはバイトオーダー指定文字が含まれます。

 

バイトオーダー 0x11223344
の出力例
「今日は」の出力結果
ビッグエンディアン 0x11223344 00 00 FE FF   00 00 4E CA
  00 00 65 E5   00 00 30 6F
リトルエンディアン(8bit x 4) 0x44332211 FF FE 00 00   CA 4E 00 00
  E5 65 00 00   6F 30 00 00
リトルエンディアン(8bit x 2 x 2) 0x22114433 00 00 FF FE   00 00 CA 4E
  00 00 E5 65   00 00 6F 30
リトルエンディアン(16bit x 2) 0x33441122 FE FF 00 00   4E CA 00 00
  65 E5 00 00   30 6F 00 00

 

 


 
 
 

UTF-8

 

UTF-8 は次のようなエンコーディングになっています。 u1-u7はそれぞれ8ビット値です。
 
UTF-8 のエンコーディング方法
 
  1. 0x00-0x7F (1Byte) の範囲の場合
    1. u1 = ucode;
    2. u1 を出力
     
  2. 0x0080-0x7FF (2Byte) の範囲の場合
    1. u1 = ((ucode >> 6) & 0x1F) | 0xC0;
    2. u2 = (ucode & 0x3F) | 0x80;
    3. u1,u2 の順に出力
     
  3. 0x0800-0xFFFF (3Byte) の範囲の場合
    1. u1 = ((ucode >> 12) & 0x0F) | 0xE0;
    2. u2 = ((ucode >> 6) & 0x3F) | 0x80;
    3. u3 = (ucode & 0x3F) | 0x80;
    4. u1,u2,u3 の順に出力
     
  4. 0x00010000-0x001FFFFF (4Byte) の範囲の場合
    1. u1 = ((ucode >> 18) & 0x07) | 0xF0;
    2. u2 = ((ucode >> 12) & 0x3F) | 0x80;
    3. u3 = ((ucode >> 6) & 0x3F) | 0x80;
    4. u4 = (ucode & 0x3F) | 0x80;
    5. u1,u2,u3,u4 の順に出力
     
  5. 0x00200000-0x03FFFFFF (5Byte) の範囲の場合
    1. u1 = ((ucode >> 24) & 0x03) | 0xF8;
    2. u2 = ((ucode >> 18) & 0x3F) | 0x80;
    3. u3 = ((ucode >> 12) & 0x3F) | 0x80;
    4. u4 = ((ucode >> 6) & 0x3F) | 0x80;
    5. u5 = (ucode & 0x3F) | 0x80;
    6. u1,u2,u3,u4,u5 の順に出力
     
  6. 0x04000000-0x7FFFFFFF (6Byte) の範囲の場合
    1. u1 = ((ucode >> 30) & 0x01) | 0xFC;
    2. u2 = ((ucode >> 24) & 0x3F) | 0x80;
    3. u3 = ((ucode >> 18) & 0x3F) | 0x80;
    4. u4 = ((ucode >> 12) & 0x3F) | 0x80;
    5. u5 = ((ucode >> 6) & 0x3F) | 0x80;
    6. u6 = (ucode & 0x3F) | 0x80;
    7. u1,u2,u3,u4,u5,u6 の順に出力
     

 

UTF-8の特徴としてエンコード後もエンコード前と同じ辞書順 を保つことができる事が挙げられます。
また、文字の先頭バイトを簡単に検出できるという特徴もあります。 ( (バイト) & 0xC0 != 0x80 なら先頭バイト )
エンコーディング方法を見るとわかりますが、Unicode にも 適応できます。

 

最後に簡単な例を挙げます。
 
文字列 im ada
UCS-4 0x00690x006D0x0061 0x00640x0061
UTF-8 0x690x6D0x61 0x640x61

文字列 (改行)
UCS-4 0x306E0x597D0x304D 0x306A0x000A
UTF-8 1110 0011
10 000001
10 101110
1110 0101
10 100101
10 111101
1110 0011
10 000001
10 001101
1110 0011
10 000001
10 101010
 
0xE3 0x81 0xAE0xE5 0xA5 0xBD 0xE3 0x81 0x8D0xE3 0x81 0xAA 0x0A

 


 
 
 

UCS-2 / UTF-16

 

UTF-16 は1文字を16ビットであらわす Unicode の標準的なコーディング 方法です。 ( UTF-16 はこれに加えて 0x10000-0x10FFFF の範囲を以下で示す方法で 32 ビットであらわします。 ) UCS-4 のエンコードは出来ません。
表現できる文字の範囲を 0 〜 0xFFFF までに限った場合は UCS-2 と呼ばれます。

 

UCS-2 / UTF-16 のエンコーディング方法
 
  1. 0x0000 〜 0xD7FF, 0xE000 〜 0xFFFD の範囲
    そのまま 16 ビットで表示
     
  2. ( 0xFFFE, 0xFFFF には何も割り当てられていない )
     
  3. ( 0xD800 〜 0x DFFF はサロゲートエリアといわれていて 文字が割り当てられておらず、0x010000 〜 0x10FFFF を 表現するのに用いられる。)
     
  4. 0x010000 〜 0x10FFFF の範囲 ( UCS-2 はこの範囲は表現できません )
    コード番号から 0x010000 を引く( 0x00000 〜0xFFFFF )
    10 ビットずつ にわける。
    4-1. (上位10ビット) | 0xD800 を最初の 16 ビットとする。
    4-2. (下位10ビット) | 0xDC00 を次の 16 ビットとする。
     
各 16 ビットはビックエンディアンとリトルエンディアンの 2通りがあります。UCS-4 同様 バイトオーダーの指定が出来ます。 UCS-4 の説明の例と同じ文字列の例を次に示します。 UCS-4 同様バイトオーダーの指定文字 0xFEFF を付けた出力結果 になっています。バイトオーダー指定文字は省略可能です。

 

バイトオーダー 0x1122
の出力例
「今日は」の出力結果
ビッグエンディアン 0x1122 FE FF   4E CA   65 E5   30 6F
リトルエンディアン 0x2211 FF FE   CA 4E   E5 65   6F 30

 


 
 
 

UTF-7

 

電子メールで Unicode 文章を交換するためのコーディングです。 電子メールでは1バイトのうち8ビット目は使用できません。 また、電子メールのサブジェクト(メールの件名 ) の部分では さらに文字が限定されます。

 

今田の勉強不足のせいで、電子メールをUnicodeで書く時のヘッダの 書き方 ( ヘッダ情報にこのメールが UTF-7 で書かれてますよという情報を どうやって指定するか ) がわかりません。 ここに書かれてある情報だけでは Unicode で書かれたメールを送る ことはできませんのであしからず。

 

UTF-7 のエンコーディング方法
 
  1. まず一旦 UTF-16 ( リトルエンディアン・バイトオーダマークなし )
  2. 以下の UTF-16 から UTF-7 へのコーディング方法に従いコーディングします。

 

UTF-16 から UTF-7 へのエンコーディング方法
 
  1. A-Z a-z 0-9 '(),-./:? space TAB CR LF
    は 1バイトで出力
    ! " # $ % & * ; < = > @ [ ] ^ _ ` { | }
    も1バイトで表示する ことが許されますが、推奨はされていません。
     
  2. + は "+-" ( 1バイト×2 ) を出力
     
  3. その他は BASE64 で出力する
     
    • まず "+" ( 1バイト ) を出力
       
    • 6ビットずつ区切って (A-Z, a-z, 0-9, +, /) で出力
       
    • 次の文字が BASE64 での出力なら続けて出力
       
    • BASE64 以外で出力する場合は '-' を出力するか、 そのまま出力 ( A-Z, a-z, 0-9, +, /, - 以外 )
       
    • 余ったビットは BASE64 のパッドはつかわず、 0 を補充して6ビットにして出力
       
    • BASE64 以外の文字に戻る場合は '-' を出力する. BASE64 以外の文字(制御文字含む)を出力する事でも BASE64 から抜けます.
       

 

説明がいいかげんなので例を挙げてフォローします。
imadaの好きな
アーチスト

という文章を UTF-7 に変換します。
まず、UTF-16(リトルエンディアン) に変換すると次の通り。

 

  im ad a
UTF-16 0x00690x006D 0x00610x0064 0x00610x306E 0x597D0x304D

  (改行)  
UTF-16 0x306A0x000A 0x30A20x30FC 0x30C10x30B9 0x30C8 

 

BASE64 部を6ビットずつ区切り、UTF-7に変換すると 次のようになります。

 

  im ad a
BASE64       
UTF-7 0x690x6D 0x610x64 0x61
im ad a

   の好きな  (改行)
BASE64   0x0C 0x06 0x39 0x19 0x1F 0x13 0x01
0x0D 0x0C 0x06 , 4ビット 1010 余 -> 0x28
  
UTF-7 0x2B 0x4D 0x47 0x35 0x5A 0x66 0x54 0x42
0x4E 0x4D 0x47 0x6F
0x2D0x0A
+ MG5ZfTBNMGo -(改行)

    アーチスト 
BASE64   0x0C 0x0A 0x08 0x30 0x3F 0x03 0x03 0x01
0x0C 0x0B 0x24 0x30 0x32 , 2ビット 00 余 -> 0x00
 
UTF-7 0x2B 0x4D 0x4B 0x49 0x77 0x2F 0x44 0x42
0x4D 0x4C 0x55 0x77 0x79 0x41
0x2D
+MKIw/DDBMLkwyA -

 

例のエンコーディング結果
imada+MG5ZfTBNMGo-
+MKIw/DDBMLkwyA-
になります。
コーディング方法はこれ以外にも多数あります。
以下例を挙げます。

 

imada+MG5ZfTBNMGo
+MKIw/DDBMLkwyA-
imada+MG4-+mn0-+ME0-+MGo-
+MKIw/DDBMLkwyA-
i+AG0AYQBo-a+MG5ZfTBNMGo
+MKIw/DDBMLkwyA-
 

 

左上の例は BASE64 から抜けるのに '-' を使わず、改行(0x0A) で代用したものです。
右上の例は "の好きな" の部分について一文字ごとに BASE64 から抜けています。
左下の例のように A-Z, a-z, 0-9, +, / をBASE64で表示しても かまいません。

 


Copyright (C)   1999-2004   いまでぃ    All Rights Reserved.
本ホームページに掲載・使用されている全ての画像及び文章の無断使用・転載を禁止します。
本ホームページの内容について いまでぃ は一切保証いたしません。
本ホームページはリンクフリーです。


製作  いまでぃ  
最終更新日  2004/07/11
文字コードの解説に戻る