UTF-8のまとめ情報

UTF-8』の解説

UTF-8(ユーティーエフはち、ユーティーエフエイト)はISO/IEC 10646 (UCS) とUnicodeで使える8ビット符号単位の文字符号化形式及び文字符号化スキーム

正式名称は、ISO/IEC 10646では “UCS Transformation Format 8”、Unicodeでは “Unicode Transformation Format-8” という。両者はISO/IEC 10646とUnicodeのコード重複範囲で互換性がある。RFCにも仕様がある。

2バイト目以降に「/」などのASCII文字が現れないように工夫されていることから、UTF-FSS (File System Safe) ともいわれる。旧名称はUTF-2。

UTF-8は、データ交換方式・ファイル形式として一般的に使われる傾向にある。

当初は、ベル研究所においてPlan 9で用いるエンコードとして、ロブ・パイクによる設計指針のもと、ケン・トンプソンによって考案された。

エンコード体系

ASCII文字と互換性を持たせるために、ASCIIと同じ部分は1バイト、その他の部分を2-6バイトで符号化する。4バイトのシーケンスでは21bit (0x1FFFFF) まで表現することができるが、Unicodeの範囲外となる17面以降を表すもの(U+10FFFFより大きなもの)は受け付けない。また5-6バイトの表現は、ISO/IEC 10646による定義とIETFによるかつての定義で、Unicodeの範囲外を符号化するためにのみ使用するが、Unicodeによる定義とIETFによる最新の定義では、5-6バイトの表現は不正なシーケンスである。

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

Unicodeの符号位置を2進表記したものを、上のビットパターンのx, yに右詰めに格納する。最短のバイト数で符号化するため、yの部分には最低1回は1が出現する。符号化されたバイト列は、バイト順に関わらず左から順に出力する。これにより4バイトで21bit、6バイトで31bitまで表現することができる。

1バイト目の先頭の連続するビット "1"(その後にビット "0" が1つ付く)の個数で、その文字のバイト数がわかるようになっている。また、2バイト目以降はビットパターン "10" で始まり、1バイト目と2バイト目以降では値の範囲が重ならないので、文字境界を確実に判定できる。すなわち、任意のバイトの先頭ビットが "0" なら1バイト文字、"10" なら2バイト以上の文字の2番目以降のバイト、"110" なら2バイト文字の先頭バイト、"1110" なら3バイト文字の先頭バイト、"11110" なら4バイト文字の先頭バイトであると判定できる。

7バイト以上の文字は規定されないため、0xFE、0xFFは使用されない。このため、バイト順マーク (BOM) に0xFEと0xFFを使用するUTF-16やUTF-32が、UTF-8と混同されることはない。

メリット

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

デメリット

  • UTF-8による符号化では、漢字仮名などの表現に3バイトを要する。このように、東アジアの従来文字コードではマルチバイト符号を用いて1文字2バイトで表現されていたデータが、1.5倍かそれ以上のサイズとなる。同様に、ISO/IEC 8859-1では1バイトで表現できた非ASCIIのラテン文字(ウムラウト付きの文字など)も2バイトとなるし、その他のISO/IEC 8859シリーズに属する文字符号ではデータ量がさらに増大しうる。
    • なお、1バイトが9ビットである処理系では、この問題をあまり発生させずに符号化できるはずである。このアイディアに基づいたジョークRFCがRFC 4042 “UTF-9” として2005年エイプリルフール4月1日)に公開された。
  • ただし、Unicodeでは一部の文字を合成によって表現することもできるから(例:「ぱ」は、U+3071のほかにもU+306F U+309Aでも表現できる)、Unicodeを採用する場合、文字列の文字数をその文字列のバイト数から計算できないことは、UTF-8に限ったことではない。
  • 最短ではない符号やサロゲートペアなど、UTF-8の規格外だがチェックを行わないプログラムでは一見正常に扱われるバイト列が存在する。これらのバイト列を入力として受け入れてしまうと、プログラムが予期しない範囲のデータを生成するため、セキュリティ上の脅威となりうる。

サロゲートペアの扱い

UTF-16ではサロゲートペアで表されるような、基本多言語面外の符号位置をUTF-8で表す時は、変換元がUTF-16でサロゲートペアの時には U+D800 ~ U+DBFF, U+DC00 ~ U+DFFF を表すUTF-8にそのまま変換したりはせず、U+10000 ~ U+10FFFF の符号位置にデコードしてから変換する。そのままUTF-8で符号化したような列は不正なUTF-8とされる。

サロゲートペアのままUTF-8と同等の符号化を行う符号化は、CESU-8 (Compatibility Encoding Scheme for UTF-16: 8-Bit) として別途定義されている。実用に供されている例としては、Oracle Databaseのバージョン8以前において、UTF-8として3オクテットまでのオクテット列しか扱えなかったために定義されたものである。本来のUTF-8における4オクテット列の代わりに、サロゲート符号位置を表す3オクテット列のペア(上位が ED A0 80 ~ ED AF BF、下位が ED B0 80 ~ ED BF BF)で表現される。

現在のOracle Databaseでも、CESU-8を「UTF8」として、「普通のUTF-8」を「AL32UTF8」として扱っているため注意を要する。MySQLでも「utf8」を指定した場合は4オクテット列が扱えず、CESU-8相当の符号化を必要とする(4オクテット列対応のUTF-8は「utf8mb4」として別途定義されているが、MySQL 5.5.3以降でないと使用できない)。

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

セキュリティ

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

ISO/IEC 10646の定義が5バイト以上の表現を許容していることにより、正しくない実装を行ったバグのあるシステムにおいてエンコード時にバッファオーバーフローが発生する可能性も指摘されている。

バイト順マークの使用について

UTF-8で符号されたテキストデータはエンディアンに関わらず同じ内容になるので、バイト順マーク (BOM) は必要ない。しかし、テキストデータがUTF-8で符号化されていることの標識として、データの先頭にEF BB BF(16進。UCSでのバイト順マークU+FEFFのUTF-8での表現)を付加することが許される。一部のテキスト処理アプリケーション(エディタなど)がこのような動作をする(TeraPadEmEditorエディタのように付加するかどうかを選択できるものもある)。

なお、日本の特殊事情として、このシーケンスがある方をUTF-8、ない方を特にUTF-8Nと呼ぶこともあるが、このような呼び分けは日本以外ではほとんど知られておらず、また公的規格などによる裏付けもない。

このシーケンスを通常の文字と認識するプログラムでは、先頭に余分なデータがあるとみなされて問題となることがある。例えば、Unix系OSにおける実行可能スクリプトは、ファイル先頭が「#!」から始まるとき、それに続く文字列をインタプリタのコマンドとして認識するが、多くのシステムでは、このシーケンスが存在するとこの機能が働かず実行できない。PHPでは、

逆にこのシーケンスがないとUTF-8と認識できないプログラムも存在する。とくにASCII部以外の文字が少ない場合に誤認することが多い(たとえば、Microsoft Excelでは、CSVファイルを開くとき、このシーケンスが付加されていないUTF-8の場合は正常に読み込むことができない。Microsoft Windowsに付属するメモ帳ワードパッドも同様。)。

プロトコルが常にUTF-8である事を強制しているものである場合はこのシーケンスを禁止するべきで、この場合ファイル先頭にこのシーケンスが現れると “ZERO WIDTH NO-BREAK SPACE” と見なされる。逆にプロトコルがそれを保証しない場合このシーケンスは禁止されずファイル先頭のそれはバイト順マークと見なされる。

参考資料

  • 用語の日本語表記は原則として「」にならった。

UTF-8』に 関連する人気アイテム

「プログラミング」のキホン プログラムの動作の基本と高速データ処理のしくみ

5つ星のうち 4.0ほんとうの基本。

(参考になった人 6/6 人)

2進数とか16進数とかプログラミングに初歩の基本的なことが、図解で掲載されている。 学生時に数学でこの辺りのことをやってきてない人には、こちらも必要であると感じた。 とくにマイコン制御やネットワークがらみだと、16進数とか2進数や何ビットとかが C言語の入門書だけではこの辺りの解説はなくいきなりこうなるからこうだ言った書き方で、 きちんと仕組みを理解しないと、誤った制御等になってしまうので、この本は自分が 捜し求めていたものだったので、満足できた。

UTF-8』の解説 by はてなキーワード

Unicode (or UCS) Transformation Format, 8-bit encoding form.

Unicodeでは Unicode Translation Format-8

UCS Transformation Format

UnicodeUCS)のエンコーディング方法のひとつ。

ASCIIの範囲内にある文字は1バイトに、大抵の漢字や仮名は3バイトにエンコーディングする特徴がある。

RFC 2279で、UCS(Unicodeのコード値)からの変換方法が定義されている。

UCS-4 range (hex.)           UTF-8 octet sequence (binary)
0000 0000-0000 007F   0xxxxxxx
0000 0080-0000 07FF   110xxxxx 10xxxxxx
0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
0001 0000-001F FFFF   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
c.f. Invalid sequence
0020 0000-03FF FFFF   111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0400 0000-7FFF FFFF   1111110x 10xxxxxx ... 10xxxxxx

詳しくはRFC 3629を参照してください。

IETFにより、STD番号(STD63)が割り振られている。

UTF-8』by Google Search

This page is provided by Matome Project.
Contact information.