2005年12月20日 11:45 [Edit]

備忘録: Unicode, UCS, and UTF

まだ混乱が収まっていらっしゃらないようなので、備忘録を兼ねてここでまとめておきましょう。

quinta essentia - del.icio.us買収, Yonah
あってるかな?

Character Set (文字集合) vs. Encoding (符号化)

まずこの二つが別物だということを抑えましょう。UCSというのは名前からわかる通り、Character Set (文字集合)です(とはいえ、Unicode.orgのGlossaryを見ると、符号化の一手段にも見えなくはない)。この段階では、各文字は「背番号」を持っているに過ぎません。狭義の「Unicode」はこの「背番号」を指します。

これをどう実際のデータにするのかがEncoding (符号化)。UTF (Unicode Transfer Format) はUnicodeにおけるその規格、現在UTF-7、UTF-8、UTF-16、UTF-32の4種類があり、うちUTF-16とUTF-32はさらにEndian別に-BE、-LEに分かれます。さらにUnicode.orgの規格ではないけどUnicodeを符号化する手法としてはPunicodeなんてのもあります(後述)

原理的に、UnicodeではU+0000からU+7FFFFFFFまでの2^31種類の文字を割り当てる事ができますが、現規格ではUTF-16でも符号化しきれるU+0000からU+10FFFFまでの17*2^16種類しか使わない決まりになっています。

UTF-7

これはUnicodeを7-bitの文字列に符号化するための規格。U+7FFFFFFFまで符号化できます。例えば「小飼弾」は+XA+Y/F8+-となります。あまり使われていません。

UTF-8

現在最も使われているUnicodeの符号化規格がこれです。U+7FFFFFFFまで符号化できます。例えば「小飼弾」はbyte表記で[e5 b0 8f e9 a3 bc e5 bc be]となります。

UTF-16やUTF-32と違ってエンディアンによる問題がなく、ASCIIはそのまま符号化するため、I18N(国際化)を考慮していない昔のソフトでもほぼ無修正で扱える(ただしこの場合には、あくまでbyte列を右から左に流しているだけで、きちんと文字を文字として扱っていないことに注意)、文字列の境界がはっきりしている*0などの扱いやすい特長が多いため普及が進みました。

ただし、漢字はほとんど3byte表記になるため、特に日本語環境では少しかさばるという欠点もあります。

UTF-16

U+0000からU+FFFFまではそのまま16bit整数、U+10000からU+10FFFFまではいわゆる Surrogate Pair という一対の16bit整数で符号化する規格。Javaでcharというとこれになります。U+10FFFFまでしか符号化できません。Unicodeの現規格の制限はここから来ています。

Windows、Mac OS Xなど多くのOS、そしてJavaの内部文字コードとしてよく使われています。

実はこの規格、Unicodeを巡る混乱の大本にもなっています。当初Unicodeはあくまで16bitに収まる範囲の文字集合を想定していたのにも関わらず、「やっぱり足りない」ということになって泥縄的にこの規格が加わったのです。この辺の混乱とUnicodeコンソーシアムの強引さは、冒頭で紹介した「電脳社会の日本語」に詳しく説明されています。

quinta essentia - del.icio.us買収, Yonah
"Unicode"という表現にバージョンまで付記しないと混乱するなぁ。

バージョンで言うと2.0以降。はっきり言ってそれ以前の規格はシカトして構いません。

UTF-32

U+0000からU+7FFFFFFFまで、全部そのまま素直に32bit整数で表記したのがこの規格。最も「素直な」規格ですが、最も使われていません。

Punycode

国際化ドメインで採用された符号化規格。既存のDNS Serverでそのまま扱えるように符号化するのが特長です。RFC 3492で規格化されています。プロ以外はあまり知る必要のない規格でしょう。

UnicodeとPerl

Perl 5.8では内部で扱う文字コードもUTF-8です。それ以外のUTFはすべてEncodeモジュールで扱うことが出来ます。ちなみに私がメンテしております。

Punycodeに関しては、miyagawa君Encode::Punycodeをリリースしているので、それをCPAN経由でInstallするだけで使えるようになります--なるはずだったのですが、Punycode規格成立前のReleaseだったのか、Test Suiteがスエてます(xn---が頭に付いていない)。というわけでmiyagawa君の早急なる対応をきぼんぬ:-)

Dan the Encode Maintainer


  1. 先頭octetの上位2bitは常に10以外、2octet目以降の上位2bitは常に10

この記事へのトラックバックURL

この記事へのトラックバック
文字集合(Character Set)と符号化(Encoding)について、より適切な表現と追補すべきネタがあったのでEntry quinta essentia - Character Set vs. Encodingとなって、U+7FFFFFFF まで許すという話もあって、ややこしさが増す。
追記: UTF-8 vs. ISO-10646【404 Blog Not Found】at 2005年12月20日 14:07
ツッコミが入ってくれて良かったー。 昨日の、 [http://d.hatena.ne.jp/quintia/20051219/1134981283:title] の件でトラックバックがありました。 Character Set (文字集合) vs. Encoding (符号化) まずこの二つが別物だということを抑えましょう。UCSというのは名前から...
[tech]Character Set vs. Encoding【quinta essentia】at 2005年12月20日 13:29
この記事へのコメント
行き摺りさん、
あ、本当ですね。直しました。古い記事なのにありがとうございます。
Dan the Typo Generator
Posted by at 2006年12月08日 16:11
誤:U+0000からU+10FFFFまではいわゆる…
正:U+10000からU+10FFFF…
では。
Posted by 行き摺り at 2006年12月08日 13:06
>通りすがり
Thanx, revised.

Dan the Man to Err
Posted by at 2005年12月26日 10:43
UTF-8の文字区切りの説明が間違ってます。正しくは「先頭のオクテットの上位2ビットは常に10以外であり、2オクテット目以降の上位2ビットは常に10」です。
Posted by 通りすがり at 2005年12月25日 04:41
MIME の Content-Type: に出てくる charset パラメータは、Character Set でなく Encoding を示すものだったりしますね。RFC2045 での Character Set の説明にもその辺りコメントが入ってたりします。
Posted by shige at 2005年12月20日 17:09
IDNA::Punycode のメンテナを譲ったのですが Encode::Punycode を hand-off していませんでした。こっちも同時にメンテナンスしてもらわないと。。
Posted by miyagawa at 2005年12月20日 11:51