UTF-8
出典: フリー百科事典『ウィキペディア(Wikipedia)』
| Unicode |
| 符号化方式 |
| UTF-7 |
| UTF-8 |
| CESU-8 |
| UTF-16/UCS-2 |
| UTF-32/UCS-4 |
| UTF-EBCDIC |
| SCSU |
| Punycode (IDN/IDNA) |
| GB 18030 |
| その他 |
| UCS |
| マッピング |
| 書字方向 |
| BOM |
| 漢字統合 |
| UnicodeとHTML |
| Unicodeと電子メール |
| Unicodeフォント |
UTF-8(旧UTF-2)はISO/IEC 10646(UCS)とUnicodeで使える8ビット符号単位の文字符号化形式及び文字符号化スキーム。 正式名称は、ISO/IEC 10646では'UCS Transformation Format 8'、Unicodeでは'Unicode Transformation Format-8'という。 両者はISO/IEC 10646とUnicodeのコード重複範囲で互換性がある。 2バイト目以降に'/'などのコードが現れないように工夫されていることから、'UTF-FSS'(File System Safe)ともいわれる。 RFCにも仕様がある。
データ交換方式、ファイル形式としては一般的にUTF-8が使われる傾向がある。 LinuxやMac OS Xのように、OSの標準文字エンコードとして使用される例も増えている。
当初は、ベル研究所において Plan 9で用いるエンコードとして、ロブ・パイクによる設計指針のもと、ケン・トンプソンによって考案された[1]。
目次 |
[編集] エンコード体系
ASCII文字と互換性を持たせるために、ASCIIと同じ部分は1バイト、その他の部分を2〜6バイトで符号化する。4バイトのシーケンスでは21bit(0x1FFFFF)まで表現することができるが、Unicodeの範囲外となる17面以降を表すもの(U+10FFFFより大きなもの)は受け付けない。また5〜6バイトの表現は、ISO/IEC 10646による定義[2]とIETFによるかつての定義[3]で、Unicodeの範囲外を符号化するためにのみ使用するが、Unicodeによる定義[4]とIETFによる最新の定義[5]では、5〜6バイトの表現は不正なシーケンスである。
ビットパターンは以下のようになっている。
0xxxxxxx (00-7f) 7bit 110yyyyx 10xxxxxx (c0-df)(80-bf) 11bit 1110yyyy 10yxxxxx 10xxxxxx (e0-ef)(80-bf)(80-bf) 16bit 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx (f0-f7)(80-bf)(80-bf)(80-bf) 21bit 111110yy 10yyyxxx 10xxxxxx 10xxxxxx 10xxxxxx (f8-fb)(80-bf)(80-bf)(80-bf)(80-bf) 26bit 1111110y 10yyyyxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx (fc-fd)(80-bf)(80-bf)(80-bf)(80-bf)(80-bf) 31bit
Unicodeの符号位置を2進表記したものを、上のビットパターンのx, yに右詰めに格納する。 最短のバイト数で符号化するため、yの部分には最低1回は1が出現する。 符号化されたバイト列は、バイト順に関わらず左から順に出力する。 これにより4バイトで21bit、6バイトで31bitまで表現することができる。
1バイト目の上位ビットの1の個数でその文字のバイト数が判るようになっている。また、2バイト目以降は10で始まり、1バイト目と2バイト目以降では値の範囲が重ならないので、文字境界を確実に判定できる。
7バイト以上の文字は規定されないため、fe, ffは使用されない。このため、バイト順マーク[6] (BOM) にfeとffを使用するUTF-16が、UTF-8と混同されることはない。
[編集] 特徴
[編集] メリット
- バイトストリーム中の任意の位置から、その文字、前の文字、あるいは次の文字の先頭バイトを容易に判定することができる。
- 文字列の検索を単なるバイト列の検索として行っても、文字境界と異なる個所でマッチしてしまうことがない。たとえばShift_JISで「¥」を検索すると「表」の2バイト目にマッチしたり、EUC-JPで「海」を検索すると「ここ」にマッチしたりするのと同様のことが起きない。このため、マルチバイト文字を意識せず、ISO 8859-1などの8bit文字向けに作られた膨大なプログラム資産を、比較的少ない修正で再利用できる。
- 但し、他のUnicodeの符号化と同様に、単にバイト列の比較では文字列が同一か判断できない場合がある。詳細は、Unicodeの等価性及び正規化を参照のこと。
- UTF-16やUTF-32と異なり、バイト単位の入出力を行うため、バイト順の影響が無い。
- 31bitまで表現できるため、サロゲートペアを使用する必要がない。
- ASCII文字が主体の文書であれば、ほとんどデータサイズを増やさずにUnicodeのメリットを享受できる。UTF-16やUTF-32では、データサイズはほぼ2倍、4倍となる。
- 複数のUTF-8文字列を、単なる符号無し8bit整数の配列とみなして辞書順ソートした結果は、Unicodeの符号位置の辞書順のソート結果(すなわちUTF-32に変換した後にソートした結果)と等しくなる。
[編集] デメリット
- UTF-8による符号化では、漢字や仮名などの表現に3バイトを要する。このように、東アジアの従来文字コードではマルチバイト符号を用いて1文字2バイトで表現されていたデータが、1.5倍かそれ以上のサイズとなる。同様に、ISO/IEC 8859-1では1バイトで表現できた非ASCIIのラテン文字 (ウムラウト付きの文字など) も2バイトとなるし、その他のISO/IEC 8859シリーズに属する文字符号ではデータ量がさらに増大しうる。
- 文字数とデータサイズが比例しないため、文字数を調べるには先頭から全データを読み取る必要がある。
- 最短ではない符号やサロゲートペアなど、UTF-8の規格外だがチェックを行わないプログラムでは一見正常に扱われるバイト列が存在する。これらのバイト列を入力として受け入れてしまうと、プログラムが予期しない範囲のデータを生成するため、セキュリティ上の脅威となりうる[7]。
[編集] サロゲートペアの扱い
UTF-16のサロゲートペア(代用対)で表されるBMP外の文字をUTF-8に変換するときは、まず4バイトのサロゲートペア(代用対)(上位代用符号単位[8] 0xD800〜0xDBFF, 下位代用符号単位[9] 0xDC00〜0xDFFF)をU+10000からU+10FFFFまでの符号位置にデコードしてからUTF-8に符号化しなければならない。サロゲートペア(代用対)に使われるU+D800からU+DFFFまでの符号位置を、UTF-8でそのまま符号化することは禁止されており、不正なシーケンスとみなされる。
サロゲートペア(代用対)を残したままUTF-8と同等の符号化を行う規格は、CESU-8(Compatibility Encoding Scheme for UTF-16: 8-Bit)として別途定義されている。 これは、Oracle Databaseのバージョン8以前において、UTF-8文字は3バイトまでしか扱えなかったために便宜的に定義されている。4バイトのサロゲートペア(代用対)は使用せず、代わりに6バイトのサロゲートペア(代用対)(上位代用符号単位がED A0 80〜ED AF BF、下位代用符号単位が ED B0 80〜ED BF BF)で表現される。 なお、現在のOracle Databaseでは、CESU-8を「UTF8」として、「普通のUTF-8」を「AL32UTF8」として扱っているため注意を要する。
また、Javaの一部の内部実装で用いられているModified UTF-8も、サロゲートペアをそのまま残す仕様となっている。 但し、NULL文字をC0 80とエンコードする(これもUTF-8規格外)点で、CESU-8とも異なる実装となっている。
[編集] セキュリティ
UTF-8のエンコード体系には冗長性があり、同じ文字を符号化するのに複数の表現が考えられる。かつてはそのような表現も許容されていたが、ディレクトリトラバーサルなどの対策として行われる文字列検査を冗長な表現によりすり抜ける手法が知られるようになったため、現在の仕様では最も短いバイト数による表現以外は不正なUTF-8シーケンスとみなさなければならない。
また、ISO/IEC 10646の定義が5バイト以上の表現を許容していることにより、注意深さの足りない実装でエンコード時にバッファオーバーフローが発生する可能性も指摘されている。
[編集] 日本語の文字とバイト数
- 1バイト
- ASCIIの全て、およびJIS X 0201ラテン文字の円記号とオーバライン以外
- 2バイト
- JIS X 0201の円記号
- JIS X 0208の非漢字の一部
- 3バイト
- 上記以外のJIS X 0201の文字
- JIS X 0208の漢字エリアの全て
- JIS X 0212の漢字エリアの全て
- JIS X 0213の第3・4水準漢字の一部
- 4バイト
- UnicodeのBMP以外全て
- JIS X 0213の第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と見なされる[10]。
[編集] Mac OS XにおけるUTF-8について
一般的にUTF-8と呼ばれる場合は、ほとんどの場合NFCで正規化されたものを表す。 一方、Mac OS Xで使用されるファイルシステムでは、ファイル名をNFDにより正規化されたUTF-8で扱う。 このため、Mac OS Xに付属するiconvでは、NFDで正規化されたUTF-8をUTF-8-MACとして扱うことができる。
なお、Mac OS Xのシステムコールでは、ファイルにアクセスする際、通常のUTF-8で指定しても内部でUTF-8-MACに変換されるため、ユーザーやプログラマはこれを意識する必要は無い。 しかし、ファイルの一覧などを取得した場合、取得されるファイル名はUTF-8-MACとなる。 これで得られたファイル名を、そのまま他のシステムにコピーすると、一般的な方法ではアクセスできないファイルが作成されてしまう恐れがあるため、十分な配慮が必要となる。
[編集] 関連項目
[編集] 脚注
- ^ RFC 3629 Page-3
- ^ ISO/IEC 10646:2003 Information technology -- Universal Multiple-Octet Coded Character Set (UCS)
- ^ RFC 2279 UTF-8, a transformation format of ISO 10646
- ^ The Unicode Standard, Version 5.0
- ^ RFC 3629 UTF-8, a transformation format of ISO 10646
- ^ Unicode Terminology English - Japanese, B, Unicode, Inc.
- ^ RFC 3629, pp.9f.
- ^ Unicode Terminology English - Japanese, H, Unicode, Inc.
- ^ Unicode Terminology English - Japanese, L, Unicode, Inc.
- ^ RFC 3629 6. Byte order mark (BOM)

