UTF-8

Article on other languages:

del.icio.us del.icio.us
Digg Digg
Furl Furl
Reddit Reddit
Rojo Rojo
Add to OnlyWire
Unicode
符号化方式
UCS
マッピング
書字方向
BOM
漢字統合
UnicodeとHTML
Unicodeと電子メール
Unicodeフォント

UTF-8(旧UTF-2)はUCS(ISO/IEC 10646)、Unicodeで使える符号化方式。 正式名称は、ISO/IEC 10646では'UCS Transformation Format 8'、Unicodeでは'Unicode Translation Format-8'という。 両者はUCS-4Unicodeのコード重複範囲で互換性がある。 2バイト目以降に'/'などのコードが現れないように工夫されていることから、'UTF-FSS'(File System Safe)ともいわれる。 RFCにも仕様がある。

データ交換方式、ファイル形式としては一般的にUTF-8が使われる傾向がある。 Linux等では、OSの標準文字エンコードとして使用される例も増えている。

当初は、Plan 9で用いるエンコードとしてベル研究所で考案された。

目次

エンコード体系

ASCII文字と互換性を持たせるために、ASCIIと同じ部分は1バイト、その他の部分を2~6バイトで符号化する。5~6バイトの表現は、ISO/IEC 10646による定義[1]IETFによるかつての定義[2]で、Unicodeの範囲外を符号化するためにのみ使用する。Unicodeによる定義[3]とIETFによる最新の定義[4]では、5~6バイトの表現は不正なシーケンスである。また4バイトのシーケンスでも、Unicodeの範囲外となる17面以降を表すものは受け付けない。

ビットパターンは以下のようになっている。

0xxxxxxx                                               (00-7f)
110yyyyx 10xxxxxx                                      (c2-df)(80-bf)
1110yyyy 10yxxxxx 10xxxxxx                             (e0-ef)(80-bf)(80-bf)
11110yyy 10yyxxxx 10xxxxxx 10xxxxxx                    (f0-f7)(80-bf)(80-bf)(80-bf)
111110yy 10yyyxxx 10xxxxxx 10xxxxxx 10xxxxxx           (f8-fb)(80-bf)(80-bf)(80-bf)(80-bf)
1111110y 10yyyyxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  (fc-fd)(80-bf)(80-bf)(80-bf)(80-bf)(80-bf)

Unicodeのコードポイントを2進表記したものを、上のビットパターンのx, yに右詰めに格納する。 最短のバイト数で符号化するため、yの部分には最低1回は1が出現する。 符号化されたバイト列は、バイトオーダーに関わらず左から順に出力する。

7バイト以上の文字は規定されないため、fe, ffは使用されない。このため、BOM付きのUTF-16とUTF-8を混同することはない。

1バイト目の上位ビットの1の個数でその文字のバイト数が判るようになっている。また、2バイト目以降は10で始まり、1バイト目と2バイト目以降では値の範囲が重ならないので、文字境界を確実に判定できる。

特徴

メリット

  • バイトストリーム中の任意の位置から、その文字、前の文字、あるいは次の文字の先頭バイトを容易に判定することができる。
  • 文字列の検索を単なるバイト列の検索として行っても、文字境界と異なる個所でマッチしてしまうことがない。たとえばShift_JISで「¥」を検索すると「表」の2バイト目にマッチしたり、EUC-JPで「海」を検索すると「ここ」にマッチしたりするのと同様のことが起きない。このため、マルチバイト文字を意識せず、ISO 8859-1などの8bit文字向けに作られた膨大なプログラム資産を、比較的少ない修正で再利用できる。(但し、他のUnicodeの符号化と同様に、単にバイト列の比較では文字列が同一か判断できない場合がある。詳細は、Unicodeの等価性及び正規化を参照のこと。)
  • UTF-16UTF-32と異なり、バイト単位の入出力を行うため、バイトオーダーの影響が無い。
  • 31bitまで表現できるため、サロゲートペアを使用する必要がない。
  • ASCII文字が主体の文書であれば、ほとんどデータサイズを増やさずにUnicodeのメリットを享受できる。UTF-16やUTF-32では、データサイズはほぼ2倍、4倍となる。

デメリット

UTF-8による符号化では、漢字仮名などの表現に3バイトを要する。このように、東アジアの従来文字コードではマルチバイト符号を用いて1文字2バイトで表現されていたデータが、1.5倍かそれ以上のサイズとなる。同様に、ISO/IEC 8859-1では1バイトで表現できた非ASCIIのラテン文字 (ウムラウト付きの文字など) も2バイトとなるし、その他のISO/IEC 8859シリーズに属する文字符号ではデータ量がさらに増大しうる (なお、1バイトが9ビットである処理系では、この問題をあまり発生させずに符号化できるはずである。このアイディアに基づいたジョークRFCRFC4042 “UTF-9” として2005年4月1日に公開された)。また、文字数とデータサイズが比例しないため、文字数を調べるには先頭から全データを読み取る必要がある。

さらに、最短ではない符号やサロゲートペアなど、UTF-8の規格外だがチェックを行わないプラグラムでは一見正常に扱われるバイト列が存在する。これらのバイト列を入力として受け入れてしまうと、プログラムが予期しない範囲のデータを生成するため、セキュリティ上の脅威となりうる[5]

サロゲートペアの扱い

UTF-16サロゲートペアで表されるBMP外の文字をUTF-8に変換するときは、まずU+10000以降の値にデコードしてから符号化しなければならない。サロゲートペアに使われるU+D800からU+DFFFまでの範囲をUTF-8でそのまま符号化することは禁止されており、不正なシーケンスとみなされる。

サロゲートペアを残したままUTF-8と同等の符号化を行う規格は、CESU-8(Compatibility Encoding Scheme for UTF-16: 8-Bit)として別途定義されている。 これは、Oracle Databaseのバージョン8以前において、4バイト以上のUTF-8文字を扱えなかったために便宜的に定義されている。 なお、現在のOracle Databaseでは、CESU-8をUTF8として、「普通のUTF-8」をAL32UTF8として扱っているため注意を要する。

また、Javaの一部の内部実装で用いられているModified UTF-8も、サロゲートペアをそのまま残す仕様となっている。 但し、NULL文字をC0 80とエンコードする(これもUTF-8規格外)点で、CESU-8とも異なる実装となっている。

なお、CESU-8等では、4バイトの文字は使用せず、代わりに前半がED A0 80からED AF BF、後半がED B0 80からED BF BFの6バイトのサロゲートペアで表現される。

セキュリティ

UTF-8のエンコード体系には冗長性があり、同じ文字を符号化するのに複数の表現が考えられる。かつてはそのような表現も許容されていたが、ディレクトリトラバーサルなどの対策として行われる文字列検査を冗長な表現によりすり抜ける手法が知られるようになったため、現在の仕様では最も短いバイト数による表現以外は不正なUTF-8シーケンスとみなさなければならない。

また、ISO/IEC 10646の定義が5バイト以上の表現を許容していることにより、注意深さの足りない実装でエンコード時にバッファオーバーフローが発生する可能性も指摘されている。

日本語の文字とバイト数

1バイト
2バイト
3バイト
4バイト


5~6バイト
  • Unicodeの範囲外(どんな文字が登録されるかという計画も無い)

バイトオーダーマークについて

UTF-8で符号されたテキストデータはエンディアンに関わらず同じ内容になるので、UTF-8で符号化されていることが確定しているのならバイトオーダーマーク (英: Byte Order Mark。以下BOM) を付加する必要はない。しかし、一部のテキスト処理アプリケーション (エディタなど) では、作成したテキストデータの先頭にBOMを付加する (付加するかどうかを選択できるものもある)。付加する場合は、EF BB BF (16進。U+FEFFのUTF-8での表現) をデータの先頭に付加する。なお、BOMありの方をUTF-8、なしの方をUTF-8Nと呼ぶこともあるが、このような呼び分けは日本以外ではほとんど知られておらず、また公的規格などによる裏付けもない。このため、UTF-8という呼び名を使っていれば情報交換の相手が文書先頭にBOMがあると見なすと期待すべきではないし、いっぽう、UTF-8Nという呼び名は情報交換の際に用いるべきではない。

BOMを付加する目的は、その文書がUTF-8であることを確実に認識できるようにするためだと考えられる。 一方で、UTF-8のBOMを認識しない(単に8ビットスルーであるというだけの、正式にはUTF-8に対応していない)プログラムでは、BOMが余分なデータとみなされて問題となる場合もある。例えば、UNIX系OSにおける実行可能スクリプトは、ファイル先頭が「#!」から始まるとき、それに続く文字列をインタプリタのコマンドとして認識するが、現状の多くのシステムでは、BOMが存在するとこの機能が働かず実行できない。ただし、これはテキストエディタで編集可能とはいえ、あくまでも実行可能な“バイナリ形式”での事例であり、テキストファイルにおけるBOMの取り扱いとは別の問題である。

逆にBOMがないとUTF-8と認識できないプログラムも存在する (とくにASCII部以外の文字が少ない場合に誤認することが多い)。

プロトコルが常にUTF-8である事を強制しているものである場合はBOMを禁止するべきで、この場合ファイル先頭のBOMは "ZERO WIDTH NO-BREAK SPACE" と見なされる。逆にプロトコルがそれを保証しない場合BOMは禁止されずファイル先頭のそれはBOMと見なされる[6]

関連項目

脚注

  1. ^ ISO/IEC 10646:2003 Information technology -- Universal Multiple-Octet Coded Character Set (UCS)
  2. ^ RFC 2279 UTF-8, a transformation format of ISO 10646
  3. ^ The Unicode Standard, Version 5.0
  4. ^ RFC 3629 UTF-8, a transformation format of ISO 10646
  5. ^ RFC 3629, pp.9f.
  6. ^ RFC 3629 6. Byte order mark (BOM)

This article is from Wikipedia. All text is available under the terms of the GNU Free Documentation License.


Giant Panda

Mercedes Car
James Bond Guide
This site monitored by SitePinger.net