■UTFとは何か■

↑
最近unicodeに対応したソフトが増加してくるにつれ、用語の混乱も一部には見られるようになってきました。そこで特に触れることの多い、UTF-7,UTF-8,UTF-16 についてここで少し取り上げておきたいと思います。

UnicodeとUCS

UnicodeはThe Unicode Consortiumが定めた文字コードの規格である。UCSはISOとIECが共同で制定したもので、ISO/IEC 10646 の規格番号が付いている。両者は大雑把にいえば同じものと考えてもよいのだが、違う機関が定めたものである故に、微妙に(?)差があるのも事実である。

■Unicode側の改訂経緯
Unicode1.0(1991) アメリカの技術者を中心に作られ、漢字コードは極めてデタラメ
Unicode1.1(1993) 中国の技術者が加わり、少しはまともになる。日本が猛反発。
Unicode2.0(1996) 日本や韓国の意見も参考に大規模な漢字のコード移動が行われる。サロゲートの考えが入って、全てを16bitで表すという理想が崩れた。
Unicode2.1(1998) 若干の文字追加
Unicode3.0(2000) 文字の追加
Unicode3.1(2001) 文字の追加
Unicode4.0(2003) 文字の追加

■UCSの改訂経緯 ISO10646-1:1993 ≒ Unicode1.1
ISO10646-1:2000 ≒ Unicode3.0 (≒JISX0221-1)
ISO10646-2:2001 (追加文字)

UCS2 2バイト(16bit)を使用するコード体系
UCS4 4バイト(32bit)を使用するコード体系

UCS4の考え方はunicode側には無い考え方である。元々UCSでは面によって言語を分ける方法で考えていたのだが、Unicode側がそれはおかしいと抗議。結果的に全てのコードを統一的に扱うUnicodeと同様の思想になったのは喜ばしいことである。

UTF-16

UTF-16とはサロゲートの処理のことである。サロゲートについて詳しいことは新unicodeの項を参照のこと。つまり3バイト以上の文字コードをUCS2相当の世界に押し込むための仕様である。

UTF-8

UTF-8とは要するにUnicodeの世界をASCIIの世界に押し込むための仕様である。Unicodeがそのまま使用できると(BMPの)全ての文字が16bitで取り扱うことができて、ひじょうに便利なのだが、どうしても8bit単位で考えたい場面も多いし、そもそも現在数字や英字などを8bit単位で処理できているものをわざわざ16bitにしてしまうとコンピュータの処理速度も大幅にダウンする。そこで極めて不愉快なこういうコードが生まれてしまったのである。

UTF-8ではUnicodeを下記のようにして、8bit文字の列に変換する

0000〜007f (ASCII) 00〜7fに変換する
0080〜07ff (各国アルファベット) c080〜dfbfに変換する
0800〜ffff (記号やCJK文字) e08080〜efbfbfに変換する
サロゲート文字 f0808080〜f7bfbfbfに変換する
つまりUTF-8ではASCII文字は1バイトで表されるが、その他の文字は2〜4バイトであらわされることになる。特に日本語の文字はほとんど3バイト(特殊な文字ではそれ以上必要なものもある)になってしまうため、極めて効率の悪いエンコーディングである。なお具体的な変換の仕方は下記の通り。
1バイト0000 0000 0aaa bbbb 0aaa bbbb
2バイト0000 0aaa bbbb cccc 110a aabb 10bb cccc
3バイトaaaa bbbb cccc dddd 1110 aaaa 10bb bbcc 10cc dddd

バリエーション

さて困ったことに、このUnicodeやUTF-8でファイルを記録する時にバリエーションが存在する。その主な点は下記の通りである。

305419896=0x12345678を0100番地に記録
Little EndianBig Endian
0100010101020103
7531
8642
0100010101020103
1357
2468
(1)Little EndianかBig Endianか
(2)BOMを付加するのか。

Endianというのは数をメモリーに格納する時に下位の数値を下位に置くのか、それとも上位の数値を先に書くのかという話であり、PentiumやAlphaはLittle Endian, SPARCやPowerPCはBig Endianである。ARMはどちらにでも切り替えられるようになっている。Unicodeでは複数のバイトを使用して文字をあらわすため、このEndian問題が生じるのである。

ここで生まれた考え方がBOM(Byte Order Mark)というものである。これはファイルの先頭にわざとFEFFという文字を書いておくのである。すると、Little Endianなら先頭の2バイトは ff, fe になり、Big Endianなら fe,ff になるから、ファイルがどちらのコードで書かれているかが分かるというものである。

しかしこのような変なコードを先頭に付けられると、いろいろな場所でひじょうに多くの問題が発生する。しばしばコンピュータシステム上の処理はファイルの先頭数文字でその種類その他を判定するようにできているのである。このため、BOMは基本的に嫌われることが多く、現在のところこれを付けるべきだと主張する人はそれほど多くない。

なおUTF-8の場合は8bitコードなのでEndian問題は生じないがBOM(UTF-8の場合は EF BB BF)を付けるかどうかの問題はある。ここでBOM無しのUTF-8のことを『UTF-8n』と呼ぶ人もいるのだが、この付近でかなりの名前の混乱がある。大雑把にいうと

実際に各仕様でデータがどのように記録されるのかの例を次節にあげる。

各仕様の出力例

下記は「TOKYO東京24時」という文字列を各仕様で出力した例である。

Code BOMEndian出力バイト列
Unicode(UCS2)Little
FFFE54004F004B0059004F007167AC4E320034004266
BOM TOKYO24
Big
FEFF0054004F004B0059004F67714EAC003200346642
BOM TOKYO24
× Little
54004F004B0059004F007167AC4E320034004266
TOKYO24
Big
0054004F004B0059004F67714EAC003200346642
TOKYO24
UTF-8
EFBBBF544F4B594FE69DB1E4BAAC3234E69982
BOM TOKYO24
UTF-8
(UTF-8n)
×
544F4B594FE69DB1E4BAAC3234E69982
TOKYO24
UTF-7×
544F4B594F2B5A 33 46 4F 72 412D32342B5A 6B 49
TOKYO東京24

各文字の変換過程(UTF-8)

文字unicode(4進)変換16進
6771(12131301)(32) 12 (2)1 31 (2)3 01E6 9D B1
4EAC(10322230)(32) 10 (2)3 22 (2)2 30E4 BA AC
6642(12121002)(32) 12 (2)1 21 (2)0 02E6 99 82

各文字の変換過程(UTF-7)

文字unicode(4進)64進Base64
東京6771 4EAC(1213 1301 1032 2230)(121 313 011 032 223 0)25 55 5 14 43 0Z3FOrA(5A 33 46 4F 72 41)
6642(1212 1002)(121 210 02[0])25 36 8ZkI(5A 6B 49)

UTF-7について

前節の最後に付けたUTF-7というのは、電子メールなどでunicodeを送信するための規格として生まれたものであるが、現実にはこの規格は普及しなかったため、現在では事実上の消滅規格となり、IETFでも非推奨規格としている。基本的なやり方は、非ASCIIの部分をBase64でエンコードして、前後に+と−を付けるというものである。非ASCIIの文字で終了している場合は最後の−は無くても良い。

この規格は若干内容に曖昧な部分もあり、それもあって数多くのバリエーションが生まれている。しかし基本的には消えていく規格であろうから、あまり気にする必要はないであろう。


(2010年頃の文書)

(C)copyright ffortune.net 1995-2016 produced by ffortune and Lumi.
お問い合わせはこちらから