UTF-8 は、電子通信で使用される文字エンコーディング規格です。Unicode標準で定義されており、その名前はUnicode Transformation Format – 8-bit に由来します。[ 1 ] 2026 年現在、ほぼすべてのウェブページ (99% ) が UTF-8 で送信されています。[ 2 ]
UTF-8は、1~4個の1バイト(8ビット)コードユニットの可変幅エンコーディングを使用して、1,112,064 [ 3 ]の有効なUnicodeコードポイントすべてをサポートします。
数値が小さいコードポイントは、出現頻度が高い傾向があり、より少ないバイト数でエンコードされます。これはASCIIとの下位互換性を考慮して設計されており、ASCIIと1対1で対応するUnicodeの最初の128文字は、ASCIIと同じバイナリ値を持つ1バイトでエンコードされるため、これらの文字のみを使用するUTF-8エンコードファイルはASCIIファイルと同一になります。拡張ASCII用に設計されたほとんどのソフトウェアはUTF-8の読み書きが可能であり、これにより、他のテキストエンコーディングよりも国際化の問題が少なくなります。[ 4 ] [ 5 ]
UTF-8はインターネット上のあらゆる国・言語において主流であり、ほとんどの規格で使用されており、多くの場合、唯一許可されているエンコーディングであり、すべての最新のオペレーティングシステムとプログラミング言語でサポートされています。
国際標準化機構(ISO) は 1989 年に、汎用マルチバイト文字セットの作成に着手しました。ISO 10646 規格の草案には、32 ビットのコードポイントのバイトストリームエンコーディングを提供するUTF-1と呼ばれる非必須の付属書が含まれていました。このエンコーディングは、パフォーマンス上の問題などから満足のいくものではなく、おそらく最大の問題は、ASCII と非 ASCII の明確な分離がなかったことです。新しい UTF-1 ツールは ASCII エンコードされたテキストとの下位互換性がありますが、UTF-1 エンコードされたテキストには、ASCII では別の意味を持つ0x21~0x7Eの範囲の継続バイトが含まれる可能性があるため、 ASCII (または拡張 ASCII ) を想定している既存のコードを混乱させる可能性があります。たとえば、Unix のパスディレクトリ区切り文字である0x2Fなどです。/
1992 年 7 月、X/Open委員会 XoJIG はより優れたエンコーディングを探していました。Unix System Laboratoriesの Dave Prosser は、実装特性が高速で、7 ビット ASCII 文字はそれ自体のみを表すように改良され、マルチバイト シーケンスには最上位ビットがセットされたバイトのみが含まれるようにする提案を提出しました。File System Safe UCS Transformation Format ( FSS-UTF ) [ 6 ]という名前とこの提案のテキストの大部分は、後に最終仕様に保持されました。[ 7 ] [ 8 ] [ 9 ] 1992 年 8 月、この提案はIBM X/Open の担当者によって関係者に配布されました。
ベル研究所のPlan 9 オペレーティングシステムグループのKen Thompsonによる修正により、自己同期が可能になり、リーダーはどこからでも開始してすぐに文字の境界を検出できるようになりましたが、以前の提案よりもビット効率がやや低下しました。また、長すぎるエンコードを防ぐバイアスの使用も廃止されました。[ 9 ] [ 10 ] Thompson の設計は、1992 年 9 月 2 日に、ニュージャージー州のダイナーでRob Pikeと共にランチョンマットに書き記されました。その後、Pike と Thompson はそれを実装し、Plan 9を更新して全体で使用するようにしました。[ 11 ]そして、その成功を X/Open に伝え、X/Open はそれをFSS-UTFの仕様として受け入れました。[ 9 ] UTF-8 は、1993 年 1 月 25 日から 29 日にかけてサンディエゴで開催されたUSENIX会議で初めて公式に発表されました。 [ 12 ]インターネット技術タスク フォースは、1998 年 1 月に、RFC 2277 ( BCP 18 )の文字セットと言語に関するポリシーで UTF-8 を採用し、古い RFC のLatin-1などのシングル バイト文字セットを置き換えて、将来のインターネット標準化作業に使用しました。[ 13 ]
UTF-8 の以前の標準規格であるRFC 2279などは、6 バイトで最大 31 ビットをエンコードすることができました。2003 年 11 月、UTF-8 はRFC 3629によってUTF-16文字エンコーディングの制約に合わせるように制限されました。高位および低位サロゲート文字に対応するコード ポイントを明示的に禁止すると、3 バイト シーケンスの 3% 以上が削除され、U+10FFFFで終了すると、4 バイト シーケンスの 48% 以上と、すべての 5 バイトおよび 6 バイト シーケンスが削除されました。 [ 14 ]
UTF-8 は、コードポイントの値に応じて、コードポイントを 1 バイトから 4 バイトでエンコードします。次の表では、それぞれ 16 進数を表す文字uからzは、 U+ uvwxyz の位置から、構成要素となる4 ビットuuuuからzzzzに置き換えられます。
例えば、文字 は 16 進コードポイントU+6841を持ち、これは2 進数では0110 1000 0100 0001となり、UTF-8 エンコーディングは11100110 10100001 10000001となります。
最初の 128 コード ポイント (ASCII) には 1 バイトが必要です。次の 1,920 コード ポイントはエンコードに 2 バイト必要で、これはほぼすべてのラテン文字アルファベットの残りの部分、IPA 拡張、ギリシャ語、キリル文字、コプト語、アルメニア語、ヘブライ語、アラビア語、シリア語、ターナおよびンコ文字、結合発音記号をカバーします。基本多言語面(BMP) の残りの 61,440 コード ポイントには 3 バイトが必要で、これにはほとんどの中国語、日本語、韓国語の文字が含まれます。1,048,576の非 BMP コード ポイントには 4 バイトが必要で、これには絵文字、あまり一般的ではないCJK 文字、その他の便利な文字が含まれます。[ 15 ]
UTF-8はプレフィックスコードであり、コードポイントの最後のバイト以降を読み取らなくてもデコードできます。Shift -JISなどの以前の多くのマルチバイトテキストエンコーディングとは異なり、自己同期型であるため、短い文字列や文字の検索が可能です。また、最大3バイト戻るだけで、任意の位置からコードポイントの開始位置を見つけることができます。先頭バイトに選択された値により、UTF-8文字列のリストをソートすると、 UTF-32文字列をソートした場合と同じ順序になります。
上記の表の行を使用して「最初のコードポイント」より小さいコードポイントをエンコードすること(つまり、必要以上にバイトを使用すること)は、オーバーロングエンコーディングと呼ばれます。これは、文字シーケンスが悪意のあるJavaScriptのブロック../などの他のセキュリティ検証を回避できるため、セキュリティ上の問題となります。MicrosoftのIIS Webサーバー[ 16 ]やApacheのTomcatサーブレットコンテナ[ 17 ]などの製品で、オーバーロングエンコーディングに関連する多数の重大な脆弱性が報告されています。したがって、オーバーロングエンコーディングはエラーとみなされ、決してデコードされるべきではありません。
すべてのバイト列が有効なUTF-8であるとは限りません。UTF-8デコーダーは、以下の内容に対応できるように準備する必要があります。
初期のUTF-8デコーダの多くは、不正なビットを無視してこれらのシーケンスをデコードしていました。巧妙に作成された不正なUTF-8シーケンスは、NUL、スラッシュ、引用符などのASCII文字をスキップまたは生成し、セキュリティ上の脆弱性につながる可能性がありました。RFC 3629には、「デコードアルゴリズムの実装は、不正なシーケンスのデコードから保護されなければならない」と記載されています。[ 18 ] Unicode標準では、デコーダに「…不正なコードユニットシーケンスをエラー状態として扱うこと。これにより、不正なコードユニットシーケンスを解釈も出力もしないことが保証される」ことを要求しています。
エラーが発生したときに例外をスローしたり、文字列を切り詰めたりするのが一般的でした[ 19 ]が、これによって、本来は無害なエラー(「ファイルが見つかりません」など)がサービス拒否攻撃になってしまいます。例えば、Python 3.0の初期バージョンでは、コマンドラインや環境変数に無効なUTF-8が含まれていると、すぐに終了していました[20]。現在では、ほとんどのコードが各エラーを単一のコードポイント( U+FFFD - 置換文字など)に置き換えて、デコードを続行します。
一部のデコーダーは、シーケンスE1,A0,20 (切り詰められた 3 バイトのコードとそれに続くスペース) を単一のエラーとみなします。これは、スペース文字を検索するとエラーの中に隠されたスペース文字が見つかるため、良い方法ではありません。Unicode 6 ( 2010 年 10 月) [ 1 ]以降、標準 (第3 章) では、エラーは 1 バイトの継続であるか、許可されていない最初のバイトで終了するという「ベスト プラクティス」が推奨されています。したがって、E1,A0,20は 2 バイトのエラーとそれに続くスペースです。エラーは 3 バイト以下で、有効な文字の開始部分を含むことはなく、 21,952 種類の異なるエラーが考えられます。多くのデコーダーは代わりに各バイトをエラーとみなします。この場合、E1,A0,20は2 つのエラーの後にスペースが続きます。これで異なるエラーは 128 種類だけになり、エラーを出力文字列に格納したり[ 20 ]、従来のエンコーディングの文字で置き換えたりすることが実用的になります。
エラーのないUTF-8バイト列は、可能なバイト列のごく一部に限られます。複数のバイト列が出現することはできず、最上位ビットがセットされたバイトが単独で存在することもできません。また、真にランダムな文字列において、最上位ビットがセットされたバイトが有効なUTF-8文字の先頭になる確率は1/15しかありません。このため、UTF-8の代わりに誤って従来のテキストエンコーディングが使用されているかどうかを容易に検出でき、システムのUTF-8への変換が容易になり、バイトオーダーマークやその他のメタデータを要求する必要がなくなります。
RFC 3629 (2003 年 11 月) 以降、 UTF-16 で使用される高および低サロゲート( U+D800からU+DFFF ) は有効な Unicode 値ではなく、それらの UTF-8 エンコーディングは無効なバイト シーケンスとして扱われなければなりません。[ 18 ]これらのエンコーディングはすべて0xEDで始まり、その後に0xA0以上が続きます。サロゲートは Windows ファイル名で許可されているため、このルールはしばしば無視され、文字列に格納する方法があるはずです。[ 21 ]これらのサロゲートの半分を許可する UTF-8 は (非公式に) WTF-8 (wobbly transformation format)と呼ばれており、[ 22 ]また、すべての非 BMP 文字を 2 つのサロゲート (4 バイトではなく 6 バイト) としてエンコードする別のバリエーションはCESU-8と呼ばれています。
以下の表は、UTF-8でエンコードされたストリーム内の各バイトの詳細な意味を示しています。
UTF-8 ファイルの先頭にUnicodeバイトオーダーマークU+FEFFがある場合、最初の 3 バイトは0xEF、0xBB、0xBFになります。
Unicode 標準では、UTF-8 に BOM を使用することを要求も推奨もしていませんが、別のエンコーディングから変換されたファイルの先頭で BOM に遭遇する可能性があると警告しています。[ 23 ] UTF-8 を使用してエンコードされた ASCII テキストは ASCII と下位互換性がありますが、Unicode 標準の推奨事項が無視され、BOM が追加された場合はそうではありません。BOM は、それに対応していないが UTF-8 を受け入れることができるソフトウェアを混乱させる可能性があります。たとえば、文字列リテラルでは非 ASCII バイトを許可しますが、ファイルの先頭では許可しないプログラミング言語などです。それにもかかわらず、UTF-8 を書き込むときに常に BOM を挿入し、最初の文字が BOM でない限り (またはファイルに ASCII しか含まれていない限り) UTF-8 を正しく解釈することを拒否するソフトウェアが、これまでも現在も存在します。
長らく、テキストをUTF-16で処理する方が良いのか、UTF-8で処理する方が良いのかという議論が盛んに行われてきました。UTF -16の主な利点は、Windows APIがすべてのUnicode文字へのアクセスにUTF-16を必須としていたことです(UTF-8は2019年5月までWindowsで完全にはサポートされていませんでした)。このため、 QtなどのいくつかのライブラリもUTF-16文字列を使用するようになり、この要件がWindows以外のプラットフォームにも伝播することになりました。
Unicodeの初期の頃は、 U+FFFFより大きい文字は存在せず、結合文字もほとんど使用されていなかったため、16ビットエンコーディングは実質的に固定サイズでした。固定サイズエンコーディングによって処理効率が向上すると考える人もいましたが、UTF-16が可変幅になった途端、そのような利点は失われました。
コードポイントU+0800 – U+FFFF はUTF-8 では 3 バイトですが、UTF-16 では 2 バイトしか占めません。このことから、中国語や他の言語のテキストは UTF-8 でより多くのスペースを占有するという考えが生まれました。しかし、テキストが大きくなるのは、これらのコードポイントが 1 バイトの ASCII コードポイントよりも多い場合のみであり、実際の文書ではマークアップ[ 24 ]やスペース、改行、数字、句読点、英単語などがあるため、このようなことはめったに起こりません。
UTF-8には、拡張ASCIIを扱えるシステムであればどんなシステムにも簡単に後付けできるという利点があり、バイト順序の問題がなく、主にラテン文字を使用する言語に比べて約半分の容量しか必要としません。


UTF-8は2008年以来、ワールドワイドウェブで最も一般的なエンコーディングとなっている。[ 26 ] 2026年1月現在 調査対象のウェブサイトの 99.0% が UTF-8 を使用しています。[ 2 ]多くのページではコンテンツの表示に ASCII 文字のみを使用していますが、現在ではエンコーディングを UTF-8 ではなく ASCII のみと宣言しているウェブサイトはごくわずかです。[ 27 ]事実上すべての国と言語で、ウェブ上での UTF-8 エンコーディングの使用率は 95% 以上です。
多くの標準はUTF-8のみをサポートしており、たとえばJSON交換ではUTF-8(バイトオーダーマーク(BOM)なし)が必要です。[ 28 ]また、HTMLおよびDOM仕様のWHATWGでもUTF-8が必須となっており、「UTF-8エンコーディングはUnicodeの交換に最も適切なエンコーディングである」と述べています。[ 5 ]また、インターネットメールコンソーシアムは、すべての電子メールプログラムがUTF-8を使用してメールを表示および作成できることを推奨しています。[ 29 ] [ 30 ] World Wide Web Consortiumは、 XMLおよびHTMLのデフォルトエンコーディングとしてUTF-8を推奨しています(UTF-8を使用するだけでなく、メタデータでも宣言します)。「すべての文字がASCII範囲内であっても...UTF-8以外のエンコーディングを使用すると、予期しない結果が生じる可能性があります」。W3C HTML仕様のバージョン5.3とWHATWGの現在のLiving StandardはどちらもUTF-8を要求しています。[ 31 ] [ 32 ]
多くのソフトウェアプログラムはUTF-8の読み書きに対応しています。通常の設定からオプションを変更する必要があるか、ファイルを読み取る最初の文字としてBOM(バイトオーダーマーク)が必要になる場合があります。UTF-8をサポートするソフトウェアの例としては、Microsoft Word [ 33 ] [ 34 ] 、 Microsoft Excel(Office 2003以降)[ 35 ] 、 Google Drive、LibreOffice [ 36 ]、およびほとんどのデータベースがあります。現在サポートされているすべてのMicrosoftオペレーティングシステム(消費者向けおよびWindows Server 2019以降)、および現在のXboxコンソールは、(UTF-16と)UTF-8をサポートしており、「Microsoft Game Development Kit(GDK)およびWindows全般はUTF-8のサポートに向けて進んでいます」[ 37 ] 。参照:Microsoft WindowsのUnicode。
UTF-8 を「デフォルト」とするソフトウェア (ユーザーが設定を変更しなくても書き込み、BOM なしで読み込む) は、2010 年以降、より一般的になっています。[ 38 ]現在サポートされているすべてのバージョンの Windows のWindows メモ帳は、BOM なしの UTF-8 をデフォルトとして書き込みます ( Windows 7メモ帳からの変更)。これにより、他のほとんどのテキスト エディタと整合性が取れるようになります。[ 39 ] Windows 11の一部のシステム ファイルでは、BOM の要件なしでUTF-8 が必要です。 [ 40 ] macOS およびほとんどの Linux ディストリビューションのほぼすべてのファイルでは、BOM なしの UTF-8 が必要です。I /Oのデフォルトが UTF-8 であるプログラミング言語には、 Ruby 3.0、[ 41 ] [ 42 ] R 4.2.2、[ 43 ] Raku、Java 18などがあります。 [ 44 ] Python 3.15 では、I/O のデフォルトが UTF-8 になります。[ 45 ] [ 46 ]以前のバージョンでは、UTF-8 の読み書きを行うオプションが必要でした。 [ 47 ] C++23では、UTF-8 が唯一の移植可能なソースコードファイル形式として採用されました。[ 48 ] open()
後方互換性は、UTF-16を使用しているコードや API をUTF-8 に変更する際の大きな障害となりますが、これは実際に行われています。2019 年 5 月、Microsoft は、アプリケーションが Windows API の「コード ページ」として UTF-8 を設定できる機能を追加し、UTF-16 を使用する必要性をなくしました。さらに最近では、プログラマーに UTF-8 の使用を推奨し[ 49 ]、「UTF-16 [...] は、複数のプラットフォームを対象とするコードに Windows が課す特有の負担である」と述べています[ 4 ] 。Go [ 50 ]、Julia、Rust、Swift (バージョン 5 以降) [ 51 ]、PyPy [ 52 ]のデフォルトの文字列プリミティブは、いずれの場合も内部的に UTF-8 を使用しています。 Python (バージョン 3.3 以降) は、Python C API 拡張機能[ 53 ] [ 54 ]および文字列[ 53 ] [ 55 ]に内部的に UTF-8 を使用し、将来のバージョンの Python では、文字列をデフォルトで UTF-8 として保存することが計画されています。[ 56 ] [ 57 ] Microsoft Visual Studioの最新バージョンは、内部的に UTF-8 を使用しています。[ 58 ]現在サポートされているすべてのバージョンの Microsoft SQL Server は、インポートとエクスポートに UTF-8 をサポートしており、さらに、メインストリーム サポートされているすべてのバージョン (SQL Server 2019 以降) は内部的に UTF-8 をサポートしており、これを使用すると、速度が 35% 向上し、「ストレージ要件がほぼ 50% 削減」されます。[ 59 ]
Java は内部的にデータ型に UTF-16 を使用しchar、結果として 、Character、StringクラスにもStringBufferUTF -16 を使用しますが[ 60 ]、I/O には「修正 UTF-8」を使用します。これは CESU-8 と同じですが、ヌル文字U+0000は0x00ではなく2 バイトのオーバーロング エンコーディング0xC0 0x80を使用します[ 61 ]。修正 UTF-8 文字列には実際のヌル バイトは含まれませんが、U+0000 を含むすべての Unicode コード ポイントを含めることができます[ 62 ]。これにより、ヌル バイトが付加された文字列を従来のヌル終端文字列関数で処理できます。Java は通常の UTF-8 をファイルやストリームに読み書きしますが[ 63 ]、オブジェクトのシリアル化[ 64 ] [ 65 ]、Java Native Interface [ 66 ] 、 Java クラス ファイルへの定数文字列の埋め込みには修正 UTF-8 を使用します。[ 62 ] Android アプリで使用される dex フォーマット ( Dalvikで定義) も、文字列値を表現するために同じ修正 UTF-8 を使用します。[ 67 ] Tclも Unicode データの内部表現には Java と同じ修正 UTF-8 [ 68 ]を使用しますが、外部データには厳密な CESU-8 を使用します。
Rakuプログラミング言語 (旧 Perl 6) は、デフォルトで入出力にエンコーディングを使用します(utf-8 Perl 5もサポートしています) 。ただし、Raku でのその選択は、「Unicode NFC (正規化形式標準)への正規化」も意味します。場合によっては、ユーザーは正規化が行われないようにしたい場合があります。そのためには、" utf8-c8" を使用できます。[ 69 ] Raku で実装されているUTF-8 Clean-8バリアントは、バイトをそのまま保持し (不正な UTF-8 シーケンスでも)、標準形式グラフェム合成を可能にするエンコーダー/デコーダーです。[ 70 ]
Pythonプログラミング言語のバージョン 3 では、無効な UTF-8 バイトストリームの各バイトをエラーとして扱います (Python 3.7 の新しい UTF-8 モードによる変更も参照してください[ 71 ] )。これにより、128 種類の異なるエラーが発生する可能性があります。UTF-8 であると想定される任意のバイト シーケンスを UTF-16 または UTF-32 にロスレスで変換できるように拡張機能が作成されました。これは、128 種類のエラー バイトを 128 個の予約済みコード ポイントに変換し、それらのコード ポイントをエラー バイトに戻して UTF-8 を出力することによって実現されます。最も一般的なアプローチは、コードをU+DC80 ... U+DCFFに変換することです。これは、 PythonのPEP 383 (または「surrogateescape」) アプローチで使用される、低い (末尾の) サロゲート値であり、したがって「無効な」 UTF-16 となります。 [ 20 ] NumPyバージョン 2.0 およびそのファイル フォーマットは、UTF-8 をサポートしています (StringDType を追加)。[ 72 ] MirBSD OPTU-8/16と呼ばれる別のエンコーディングでは、プライベート使用領域でU+EF80 ... U+EFFFに変換されます。[ 73 ]どちらの方法でも、バイト値は出力コードポイントの下位 8 ビットにエンコードされます。これらのエンコーディングは、無効な UTF-8 が Python が内部的に使用する UTF-16 への変換、そして UTF-16 からの逆変換に耐えられるようにするために必要であり、Unix ファイル名には無効な UTF-8 が含まれる可能性があるため、これが機能する必要があります。[ 74 ]
Unix ライクなシステムのほとんどのファイルシステムは、ファイル名のバイトを比較してファイル名を検索するため、UTF-8 を使用してファイル名をエンコードできます。Linux のext4と macOS のAPFSファイルシステムは、ファイル名のエンコードを指定する必要がある大文字小文字を区別しないファイル名検索をサポートしています。ext4 は UTF-8 をサポートし、デフォルトでそれを使用します[ 75 ]、APFS は UTF-8 を必須としています[ 76 ] 。Appleの古いHFS Plus はファイル名にUTF-16を使用しますが、シンボリックリンクには UTF-8 を使用します[ 77 ]。WindowsのファイルシステムNTFS は、ファイル名に UTF-16 を使用します。
エンコーディングの正式名称は でUTF-8、これはすべての Unicode Consortium 文書で使用されている綴りです。ハイフン(マイナス)は必須で、スペースは使用できません。その他の名称としては、以下のようなものがあります。
utf-8よく使用されます。utf8、 やその他の多くのエイリアスも許可されています。[ 78 ]ただし、HTML ドキュメントでは、エンコーディングを「文字列 'utf-8 'に一致する ASCII 大文字小文字を区別しない一致」として指定する必要があります。[ 31 ]csUTF8唯一のエイリアスとして[ 79 ]を挙げていますが、これはめったに使用されません。UTF-8NUTF-8 を意味し、この場合はBOM が存在することを示唆する可能性があります。 [ 80 ] [ 81 ]UTF-865001[ 82 ]CP_UTF8です。utf8mb4と呼ばれ、とは廃止されたCESU-8バリアントを指します。[ 84 ]utf8utf8mb3AL32UTF8UTF-8(バージョン9.0以降)を意味し、UTF8CESU-8(バージョン8.0以降)を意味します[ 85 ]。また、使用は推奨されていません[ 86 ] 。18N。[ 87 ]各種標準規格文書には、UTF-8に関する複数の現行定義が存在する。
これらは、以下の旧版の文献に記載されている定義に取って代わるものである。
基本的な仕組みはすべて同じだが、主な違いは、許容されるコードポイント値の範囲や、無効な入力の安全な処理方法といった点にある。
各エンコード形式は、UnicodeコードポイントU+0000..U+D7FFとU+E000..U+10FFFFをマッピングします。
.txtCSV、
通常は UTF-8 を想定します。
は、以下に示すように、新しいテキスト ファイルを BOM なしの UTF-8 として保存することをデフォルトとするようになりました。
で UTF-8 エンコーディングが使用されていることを確認してください。
UTF-8 表現は必要に応じて作成され、Unicode オブジェクトにキャッシュされます。
非推奨
メンバー
が削除されました。
wstrwstr_length
Visual Studio は、ソース文字セットと実行文字セット間の変換時に、内部文字エンコーディングとして UTF-8 を使用します。
InputStreamReaderとOutputStreamWriterDataInputとDataOutput以前は XP (および未確認だがおそらく Vista も) では、コードページ 65001 が有効な間は for ループが機能しなかった。