UTF-8

出典: Wikipedio


Template:Table Unicode 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にも仕様がある<ref>RFC 3629 UTF-8, a transformation format of ISO 10646</ref>。

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

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

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

目次

エンコード体系

ASCII文字と互換性を持たせるために、ASCIIと同じ部分は1バイト、その他の部分を2〜6バイトで符号化する。4バイトのシーケンスでは21bit(0x1FFFFF)まで表現することができるが、Unicodeの範囲外となる17面以降を表すもの(U+10FFFFより大きなもの)は受け付けない。また5〜6バイトの表現は、ISO/IEC 10646による定義<ref>ISO/IEC 10646:2003 Information technology -- Universal Multiple-Octet Coded Character Set (UCS)</ref>とIETFによるかつての定義<ref>RFC 2279 UTF-8, a transformation format of ISO 10646</ref>で、Unicodeの範囲外を符号化するためにのみ使用するが、Unicodeによる定義<ref>The Unicode Standard, Version 5.2</ref>とIETFによる最新の定義<ref>RFC 3629 UTF-8, a transformation format of ISO 10646</ref>では、5〜6バイトの表現は不正なシーケンスである。

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

Unicode ビット列 バイト列 有効ビット
U+0000……U+007F 0xxxxxxx (00-7f) Template:07bit
U+0080……U+07FF 110yyyyx 10xxxxxx (c0-df)(80-bf) 11bit
U+0800……U+FFFF 1110yyyy 10yxxxxx 10xxxxxx (e0-ef)(80-bf)(80-bf) 16bit
U+10000……U+1FFFFF 11110yyy 10yyxxxx 10xxxxxx 10xxxxxx (f0-f7)(80-bf)(80-bf)(80-bf) 21bit
U+200000……U+3FFFFFF 111110yy 10yyyxxx 10xxxxxx 10xxxxxx 10xxxxxx (f8-fb)(80-bf)(80-bf)(80-bf)(80-bf) 26bit
U+4000000……U+7FFFFFFF 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バイト以上の文字は規定されないため、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文字列を、単なる符号なし8bit整数の配列とみなして辞書順ソートした結果は、Unicodeの符号位置の辞書順のソート結果(すなわちUTF-32に変換した後にソートした結果)と等しくなる。

デメリット

  • UTF-8による符号化では、漢字仮名などの表現に3バイトを要する。このように、東アジアの従来文字コードではマルチバイト符号を用いて1文字2バイトで表現されていたデータが、1.5倍かそれ以上のサイズとなる。同様に、ISO/IEC 8859-1では1バイトで表現できた非ASCIIのラテン文字 (ウムラウト付きの文字など) も2バイトとなるし、その他のISO/IEC 8859シリーズに属する文字符号ではデータ量がさらに増大しうる。
    • なお、1バイトが9ビットである処理系では、この問題をあまり発生させずに符号化できるはずである。このアイディアに基づいたジョークRFCRFC 4042 “UTF-9” として2005年4月1日に公開された。
  • 文字数とデータサイズが比例しないため、文字数を調べるには先頭から全データを読み取る必要がある。
  • 最短ではない符号やサロゲートペアなど、UTF-8の規格外だがチェックを行わないプログラムでは一見正常に扱われるバイト列が存在する。これらのバイト列を入力として受け入れてしまうと、プログラムが予期しない範囲のデータを生成するため、セキュリティ上の脅威となりうる<ref>RFC 3629, pp.9f.</ref>。

サロゲートペアの扱い

UTF-16代用対(サロゲートペア)で表されるBMP外の文字をUTF-8に変換するときは、まず4バイトのサロゲートペア(代用対)(上位代用符号単位 0xD800〜0xDBFF, 下位代用符号単位 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)で表現される<ref>現在のOracle Databaseでは、CESU-8を「UTF8」として、「普通のUTF-8」を「AL32UTF8」として扱っているため注意を要する。</ref>。

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

セキュリティ

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

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

文字種

B Unicode スクリプト JIS X 0201 JIS X 0208 JIS X 0212 JIS X 0213
1 U+0000……U+007F ASCII Roman(円記号オーバーライン以外) - - -
2 U+0080…………U+07FF ラテンダイアクリティカルギリシャキリールアルメニアヘブライアラビアシリアターナ 円記号 非漢字の一部 非漢字の一部 非漢字の一部
3 U+0800……U+7FFF インド系諸文字句読点学術記号絵文字東アジアの諸文字、全角半角形 オーバーライン、Kana 残りの全て 残りの全て 大半
4 U+10000……U+1FFFFF 古代文字、3に含まれない漢字 - - - 第3・第4水準漢字の一部

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

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

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

逆にこのシーケンスがないとUTF-8と認識できないプログラムも存在する。とくにASCII部以外の文字が少ない場合に誤認することが多い (たとえば、Microsoft Excelでは、CSVファイルを開くとき、このシーケンスが付加されていないUTF-8の場合は正常に読み込むことができない<ref>standby.com/qa5574877.html ExcelでUTF-8の csvデータを表示するにはUTF-8で文字化け回避してCSV出力する方法を参照</ref>)。

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

Unicode正規化との関係

Template:Anchor 一般に、Unicodeにもとづくテキストデータの表現は、正規化を行わなければ一意にならない。UTF-8自体は正規化の有無に関わらずデータを符号化できる。そこで、NFCNFD、あるいはそれと類似の形式で正規化されたデータを要求するプロトコルやアプリケーションもある。

たとえば、Mac OS Xで使用されるHFS+ファイルシステムでは、ファイル名をNFDに正規化されたUTF-8で扱う。実際には、これはNFDを改変したものである。以前のMac OS用エンコーディングとの互換性を保つために、正規化から除外される文字がある<ref>Template:Cite web</ref>。Mac OS Xに付属するiconvでは、この改変されたNFDで正規化されるUTF-8を「UTF-8-MAC」として扱うことができる。

Mac OS Xのシステムコールでは、ファイルにアクセスする際、通常のUTF-8で指定しても内部で前述の正規化が行われるため、ユーザーやプログラマはこれを意識する必要はない。しかし、ファイルの一覧などを取得した場合、取得されるファイル名は正規化されたものとなる。このファイル名をそのまま他のUTF-8を使用する (しかし、NFDによる分解を前提としていない) システムにコピーすると、そのシステムの一般的な方法ではアクセスできないファイルが作成されてしまうおそれがある。

脚注

<references/>

参考資料

用語の日本語表記は原則として次にならった。Template:Cite web

関連項目

Template:文字コードar:صيغة التحويل الموحد-8 ca:UTF-8 cs:UTF-8 da:UTF-8 de:UTF-8 el:UTF-8 en:UTF-8 eo:UTF-8 es:UTF-8 fi:Unicode#UTF-8 fr:UTF-8 he:UTF-8 hr:UTF-8 hu:UTF-8 it:UTF-8 ko:UTF-8 lt:UTF-8 lv:UTF-8 ml:യു.ടി.എഫ്-8 ms:UTF-8 nl:UTF-8 nn:UTF-8 no:UTF-8 pl:UTF-8 pt:UTF-8 ru:UTF-8 sk:UTF-8 sl:UTF-8 sr:UTF-8 sv:UTF-8 tr:UTF-8 uk:UTF-8 zh:UTF-8

個人用ツール