UTF-8、UTF-16、およびUTF-32


487

UTF-8、UTF-16、UTF-32の違いは何ですか?

それらはすべてUnicodeを格納し、それぞれが文字を表すために異なるバイト数を使用することを理解しています。どちらを選択するかには利点がありますか?


36
あなたがUnicodeがどのように機能するかに興味がある場合は、このビデオをご覧youtube.com/watch?v=MijmeoH9LT4を

1
ビデオはUTF-8に焦点を当てており、はい、可変長エンコーディングがどのように機能するかをよく説明しており、固定長ASCIIのみを読み書きするコンピューターとほとんど互換性があります。Unicodeの人たちは、UTF-8エンコーディングを設計するときに賢くなりました。

1
変換と比較のためのオンラインツールを作成しました。
アミットクマールグプタ

1
UTF-8は、保存されたファイルの最新のソフトウェアの事実上の標準です。具体的には、HTMLと構成ファイルおよび翻訳ファイルで最も広く使用されているエンコーディングです(たとえば、Minecraftは、そのすべてのテキスト情報に対して他のエンコーディングを受け入れません)。UTF-32は内部メモリの表現高速で、UTF-16は一種の非推奨で、現在は歴史的な理由からWin32でのみ使用されています(UTF-16は Windows 95の時代には固定長でした)
Kotauskas

@VladislavToncharov UTF-16が固定長エンコーディングになることはありませんでした。あなたはそれをUCS-2と混同しています。

回答:


373

UTF-8は、ASCII文字が8ビットに(ASCIIのように)8ビットにエンコードするため、ASCII文字がテキストのブロック内の大部分の文字を表す場合に有利です。また、ASCII文字のみを含むUTF-8ファイルは、ASCIIファイルと同じエンコーディングを持っているという利点もあります。

UTF-16は、主に文字あたり2バイトを使用するため、ASCIIが主流ではない場合に適しています。UTF-8は、高次文字に3バイト以上を使用し始めますが、UTF-16はほとんどの文字で2バイトのままです。

UTF-32は、すべての可能な文字を4バイトでカバーします。これはかなり肥大化します。それを使うメリットは何とも言えません。


165
UTF-32の利点:たとえば文字ごとに処理するために、保存されたデータを32ビットUnicodeコードポイントにデコードする必要はありません。コードポイントは、すでに配列/ベクター/文字列のすぐそこにあります。
richq 2009年

22
(天国があなたを助ける)あなたが車輪を再実装しなければならないなら、解析するのも簡単です。
ポールマクミラン

24
まあ、UTF-8にはネットワーク転送の利点があります。一度に1バイトずつデータを転送するので(4ではなく)、エンディアンを心配する必要はありません。
TimČas、2011

30
@richqコードポイントは常に文字に対応しているとは限らないため、UTF-32では文字単位の処理を実行できません。
hamstergene

4
UTF-32の利点:文字列操作は、utf-8の同等物と比較しておそらく高速です
Wes

332

要するに:

  • UTF-8:可変幅エンコーディング、ASCIIとの下位互換性。ASCII文字(U + 0000〜U + 007F)は1バイト、コードポイントU + 0080〜U + 07FFは2バイト、コードポイントU + 0800〜U + FFFFは3バイト、コードポイントU + 10000〜U + 10FFFF 4バイトかかります。英語のテキストには適していますが、アジアのテキストにはあまり適していません。
  • UTF-16:可変幅エンコーディング。コードポイントU + 0000〜U + FFFFは2バイト、コードポイントU + 10000〜U + 10FFFFは4バイトです。英語のテキストには良くなく、アジアのテキストには良い。
  • UTF-32:固定幅エンコーディング。すべてのコードポイントは4バイトを使用します。膨大なメモリを消費しますが、操作は高速です。ほとんど使われません。

長期的には、Wikipedia:UTF-8UTF-16、およびUTF-32を参照してください。


65
@spurrymoses:私は厳密に、データバイトが占める領域の量を指します。UTF-8ではアジア系文字ごとに3バイトが必要ですが、UTF-16ではアジア系文字ごとに2バイトのみ必要です。プログラムのメモリに保存されているテキストの平均量と比較して、最近のコンピュータには大量のメモリがあるため、これは本当に大きな問題ではありません。
Adam Rosenfield、

12
UTF-32はめったに使用されなくなりました... osxおよびlinuxではwchar_tデフォルトで4バイトです。gccには、-fshort-wcharサイズを2バイトに縮小するオプションがありますが、標準ライブラリとのバイナリ互換性が失われます。
vine'th

9
@PandaWood ofcource UTF-8は任意の文字をエンコードできます!しかし、メモリ要件とUTF-16のメモリ要件を比較しましたか?ポイントを逃しているようです!
Ustaman Sangat 2011

16
Unicodeをエンコードできないものを含むすべてのエンコード形式のコンテキストで、UTF-8が「アジアのテキストにはあまり適していない」と誰かが言ったとしたら、もちろん間違っているでしょう。しかし、それは文脈ではありません。メモリ要件のコンテキストは、質問(および回答)がUTF-8、UTF-16、およびUTF-32を比較するという事実から来ています。これらはすべてアジア言語のテキストをエンコードしますが、使用するメモリ/ストレージの量は異なります。したがって、それらの相対的な良さは、当然、完全にメモリ要件のコンテキスト内にあることになります。「あまり良くない」!=「良くない」。
ポールグレゴリー

5
@McGafter:もちろんあります。信頼性が必要な場合は、Unicodeコンソーシアムで馬の口に直接行ってください。UTF- *エンコーディングの説明については、2.5章を参照してください。しかし、エンコーディングの簡単で高レベルな理解を得るために、ウィキペディアの記事のほうがはるかに親しみやすいソースであることがわかりました。
Adam Rosenfield 2013年

116
  • UTF-8は1から4バイトまでの可変長です。

  • UTF-16は可変の2または4バイトです。

  • UTF-32は4バイト固定です。

注:UTF-8は最新の規則で1〜6バイトを使用できます:https : //lists.gnu.org/archive/html/help-flex/2005-01/msg00030.html


35
UTF8は実際には1から6バイトです。
アークル2014

6
Unicode v6.3がU-0010FFFFで終わる場合でも、UTF32 / LE / BEの全範囲のマッピングにはU-00200000-U-7FFFFFFFが含まれるため、@ Urkleは技術的に正しいです。5バイトおよび6バイトのutf8をenc / decする方法の詳細な内訳は次のとおり

4
これらを関連する参照部品とそのソースでバックアップしますか?
n611x007

20
@Urkleいいえ、UTF-8は5バイトまたは6バイトにすることはできません。Unicodeコードポイントは21ビットに制限されており、UTF-8は4バイトに制限されています。(あなたはもちろん、任意の大きな整数をエンコードするUTF-8の原理を拡張することができますが、それは、Unicodeではないでしょう。)を参照してくださいRFC 3629.
RDB

11
ウィキペディアの引用:2003年11月、UTF-8はRFC 3629によってUTF-16文字エンコードの制約に一致するように制限されました:高サロゲート文字と低サロゲート文字に対応するコードポイントを明示的に禁止すると、3バイトシーケンスの3%以上が削除されました、U + 10FFFFで終了すると、4バイトのシーケンスとすべての5バイトおよび6バイトのシーケンスの48%以上が削除されました。
Adam Calvet Bohl 2017年

79

Unicodeは、単一の巨大な文字セットを定義し、1つの一意の整数値をすべてのグラフィックシンボルに割り当てます(これは大きな単純化であり、実際には当てはまりませんが、この質問の目的には十分に近いものです)。UTF-8 / 16/32は、これをエンコードするための単純に異なる方法です。

つまり、UTF-32は各文字に32ビット値を使用します。これにより、すべての文字に固定幅コードを使用できます。

UTF-16はデフォルトで16ビットを使用しますが、65kの可能な文字しか提供されません。これは、完全なUnicodeセットには十分に近いものではありません。そのため、一部の文字は16ビット値のペアを使用します。

また、UTF-8はデフォルトで8ビット値を使用します。つまり、最初の127の値は固定幅の1バイト文字です(最上位ビットは、これがマルチバイトシーケンスの始まりであることを示し、7実際の文字値のビット)。他のすべての文字は、最大4バイトのシーケンスとしてエンコードされます(メモリが機能する場合)。

そして、それは私たちに利点をもたらします。ASCII文字はUTF-8と直接互換性があるため、レガシーアプリのアップグレードでは、UTF-8が一般的で明白な選択肢です。ほとんどの場合、メモリの使用量も最小になります。一方、文字の幅は保証できません。幅は1、2​​、3、または4文字で、文字列の操作が困難になります。

UTF-32が反対である、それはほとんどのメモリを(各文字が広い固定4バイト)使用していますが、一方で、あなたが知っている文字列操作がはるかに簡単になるように、すべての文字が、この正確な長さを持っていること。文字列のバイト数から単純に文字列の文字数を計算できます。UTF-8ではそれはできません。

UTF-16は妥協です。ほとんどの文字を固定幅の16ビット値に収めることができます。したがって、中国語の記号、音符などがない限り、各文字は16ビット幅であると想定できます。UTF-32より少ないメモリを使用します。しかし、それはある意味で「両方の世界で最悪」です。ほとんどの場合、UTF-8よりも多くのメモリを使用しますが、UTF-8(可変長文字)を悩ませる問題を回避することはできません。

最後に、プラットフォームがサポートしているものをそのまま使用すると便利な場合があります。Windowsは内部でUTF-16を使用しているため、Windowsではそれが当然の選択です。

Linuxは少し異なりますが、Unicodeに準拠しているものすべてに一般的にUTF-8を使用します。

つまり、3つのエンコーディングはすべて同じ文字セットをエンコードできますが、各文字は異なるバイトシーケンスとして表されます。


12
Unicodeが各グラフィックシンボルに一意の整数を割り当てると言うのは不正確です。これは各コードポイントにそのようなものを割り当てますが、一部のコードポイントは非表示の制御文字であり、一部のグラフィックシンボルは複数のコードポイントを表す必要があります
tchrist

15
@tchrist:はい、それは不正確です。問題は、Unicodeを正確に説明するには、何千ものページを作成する必要があることです。私は、エンコーディングの違いを説明するために、全体で基本的な考え方を取得することを望んだ
jalf

@jalf lolそうですね、基本的にUnicodeを説明するには、Unicodeコア仕様
Justin Ohms

より具体的には、提供されたプリミティブから中国のシンボルを構築できます(ただし、それらは同じチャートにあるため、実際に使用するのは、ディスクまたはRAMのいずれかで非現実的な量のスペースを使用します)。組み込みのもの。
コタウカス

44

Unicodeは標準であり、UTF-xについては、いくつかの実用的な目的のための技術的な実装と考えることができます。

  • UTF-8-サイズ最適化」:ラテン文字ベースのデータ(またはASCII)に最適です。文字あたり1バイトしかかかりませんが、それに応じてサイズはシンボルの種類に応じて大きくなります(最悪の場合、文字あたり最大6バイトまで大きくなる可能性があります)。
  • UTF-16- " バランス ":文字あたり最小2バイト必要です。これは、文字処理を容易にするために固定サイズの既存の主流言語セットに十分です(ただし、サイズは可変であり、文字あたり最大4バイトまで拡張できます) )
  • UTF-32-パフォーマンス」:固定サイズの文字(4バイト)の結果として単純なアルゴリズムを使用できますが、メモリが不利です

«主流の言語»は世界の多くの地域ではそれほど主流ではありません^^
tuxayo

2
UTF-16は実際には非ASCII文字用に最適化されたサイズです。それは実際にそれが使用される言語に依存するからです。
tuxayo

@tuxayoは完全に同意します。世界のアジア地域の漢字と漢字のセットに注目する価値があります。
ルーク

一番の答えになるはずです。これは正しすぎてここに埋められません。
MichalŠtein

28

私のブログ記事で簡単な説明をしようとしました

UTF-32

符号化するために32ビット(4バイト)を必要とする任意の文字。たとえば、このスキームを使用して「A」文字のコードポイントを表すには、32ビットの2進数で65を書き込む必要があります。

00000000 00000000 00000000 01000001 (Big Endian)

よく見ると、ASCIIスキームを使用する場合、最も右側の7ビットは実際には同じビットであることに気付くでしょう。ただし、UTF-32は固定幅スキーマであるため、3バイト追加する必要があります。「A」文字のみを含む2つのファイルがあり、1つはASCIIエンコードされ、もう1つはUTF-32エンコードされている場合、それらのサイズはそれぞれ1バイトと4バイトになります。

UTF-16

多くの人々は、UTF-32がコードポイントを表すために固定幅32ビットを使用するため、UTF-16は固定幅16ビットであると考えています。違う!

UTF-16では、コードポイントは16ビットまたは32ビットのいずれかで表されます。したがって、このスキームは可変長エンコーディングシステムです。UTF-32を超える利点は何ですか?少なくともASCIIの場合、ファイルのサイズは元の4倍にはなりません(ただし、2倍になります)ので、ASCIIには下位互換性がありません。

「A」文字を表すには7ビットで十分なので、UTF-32のように4ビットではなく2バイトを使用できるようになりました。次のようになります。

00000000 01000001

UTF-8

正解です。UTF-8では、コードポイントは32、16、24、または8ビットのいずれかを使用して表される可能性があり、UTF-16システムとして、これも可変長エンコーディングシステムです。

最後に、ASCIIエンコーディングシステムを使用して表すのと同じ方法で "A"を表すことができます。

01001101

UTF-16が実際にUTF-8よりも優れている小さな例:

中国語の文字「語」を考えてみましょう。そのUTF-8エンコーディングは次のとおりです。

11101000 10101010 10011110

UTF-16エンコーディングは短いですが、

10001010 10011110

表現とそれがどのように解釈されるかを理解するには、元の投稿にアクセスしてください。


19

UTF-8

  • バイトオーダーの概念はありません
  • 1文字あたり1〜4バイトを使用します
  • ASCIIは互換性のあるエンコーディングのサブセットです
  • 完全に自己同期します。たとえば、ストリーム内の任意の場所からドロップされたバイトは、多くても単一の文字を破壊します
  • ほとんどすべてのヨーロッパ言語は文字ごとに2バイト以下でエンコードされています

UTF-16

  • 既知のバイトオーダーで解析するか、バイトオーダーマーク(BOM)を読み取る必要があります
  • 文字ごとに2または4バイトを使用します

UTF-32

  • すべての文字は4バイトです
  • 既知のバイトオーダーで解析するか、バイトオーダーマーク(BOM)を読み取る必要があります

文字の大部分がCJK(中国語、日本語、韓国語)文字スペースからのものでない限り、UTF-8が最もスペース効率がよくなります。

UTF-32は、バイト配列への文字オフセットによるランダムアクセスに最適です。


「自己同期」はUTF-8でどのように機能しますか?1バイト文字と2バイト文字の例を挙げられますか?
Koray Tugay

2
@KorayTugay有効な短いバイト文字列が長い文字で使用されることはありません。たとえば、ASCIIの範囲は0〜127です。つまり、すべての1バイト文字は0xxxxxxxバイナリ形式です。すべての2バイト文字110xxxxxは、2番目のバイトで始まります10xxxxxx。したがって、2バイト文字の最初の文字が失われたとしましょう。10xxxxxx110xxxxxxにがないことがわかり次第、バイトが失われたか破損したことを確認し、その文字を破棄(またはサーバーなどから再要求)して、有効な最初のバイトが再び表示されるまで続行できます。 。
クリス

1
文字へのオフセットがある場合は、その文字へのオフセットがあります。utf8、utf16、またはutf32は、その場合もまったく同じように機能します。つまり、バイト配列への文字オフセットによるランダムアクセスがすべて同等に優れています。utf32よりもutf8よりも文字のカウントが優れているという考えも完全に誤りです。コードポイントは、(あるいない再び、書記素と同じではない文字と同じ..ため息)、UTF32及びUTF8 8と32ビットの間で32ビット幅であるが、文字は、複数のコードポイントにまたがることができ、その人々がutf32がutf8より優れていると主張する主な利点を破壊します。
明確な

14

MySQLでUTF-8とUTF-16のデータベースパフォーマンスを比較するためにいくつかのテストを行いました。

更新速度

UTF-8

ここに画像の説明を入力してください

UTF-16

ここに画像の説明を入力してください

挿入速度

ここに画像の説明を入力してください

ここに画像の説明を入力してください

速度を削除

ここに画像の説明を入力してください

ここに画像の説明を入力してください


14

UTF-32では、すべての文字が32ビットでコード化されます。利点は、文字列の長さを簡単に計算できることです。欠点は、ASCII文字ごとに余分な3バイトを浪費することです。

UTF-8文字には可変長があり、ASCII文字は1バイト(8ビット)でコード化され、ほとんどの西部特殊文字は2バイトまたは3バイト(たとえば、€は3バイト)でコード化され、さらにエキゾチックな文字が使用される場合があります4バイトに。明らかな欠点は、アプリオリに文字列の長さを計算できないことです。しかし、UTF-32と比較して、ラテン語(英語)のアルファベットテキストをコーディングするのに必要なバイト数ははるかに少なくなります。

UTF-16も可変長です。文字は2バイトまたは4バイトでコード化されます。本当に要点はわかりません。可変長であるという欠点がありますが、UTF-8ほどのスペースを節約できるという利点はありません。

これら3つのうち、明らかにUTF-8が最も広く普及しています。


Webサイトの開発中に文字列の長さを計算したいのはなぜですか?Web開発でUTF-8 / UTF-16を選択する利点はありますか?
モルフィドン2017

「利点は、文字列の長さを簡単に計算できることです」コードポイントの数で長さを定義する場合、はい、バイト長を4で割ってUTF-32でそれを取得できます。これはあまり有用な定義ではありませんが、文字数とは関係がない場合があります。また、正規化により、文字列内のコードポイントの数が変わる場合があります。たとえば、フランス語の単語「été」は、3つの異なるコードポイント長で、少なくとも4つの異なる方法でエンコードできます。

UTF-16はおそらくUTF-8よりも高速ですが、UTF-32のようなメモリの浪費もありません。
MichalŠtein

6

開発環境によっては、文字列データ型が内部で使用するエンコーディングを選択できない場合もあります。

しかし、データの保存と交換には、選択肢があれば常にUTF-8を使用します。ほとんどの場合、ASCIIデータを使用すると、転送するデータ量が最小になり、すべてをエンコードすることができます。最小のI / Oに最適化することは、最新のマシンで実行する方法です。


間違いなく、スペース要件よりもはるかに重要なのは、UTF-8がエンディアンの影響を受けないという事実です。UTF-16とUTF-32は必然的にエンディアンの問題に対処する必要があります。UTF-8は単にオクテットのストリームです。
IInspectable 2018

2

前述のように、違いは主に基礎となる変数のサイズであり、それぞれの場合により多くの文字を表現できるように大きくなります。

ただし、フォント、エンコーディング、および物事は非常に複雑(不必要に?)なので、詳細を入力するには大きなリンクが必要です。

http://www.cs.tut.fi/~jkorpela/chars.html#ascii

すべてを理解することを期待しないでください。しかし、後で問題が発生したくない場合は、できるだけ早く(または他の人に整理してもらうこと)、できる限り学ぶ価値があります。

ポール。


または、事実上の標準となったUTF-8をデフォルトとして使用し、新しいシステムがそれをサポートしているかどうかを調べます。そうでない場合は、この投稿に戻ることができます。
robotik

-2

つまり、UTF-16またはUTF-32を使用する唯一の理由は、英語以外のスクリプトと古代のスクリプトをそれぞれサポートすることです。

Web /プログラミングの目的で明らかにより効率的であるのに、UTF-8以外のエンコーディングを選択する理由は誰なのかと思っていました。

一般的な誤解-接尾辞の付いた数字は、その機能を示すものではありません。それらはすべて、完全なUnicodeをサポートしますが、UTF-8はASCIIを1バイトで処理できるため、CPUやインターネットでの破損が少なく効率的です。

良い読書:http : //www.personal.psu.edu/ejp10/blogs/gotunicode/2007/10/which_utf_do_i_use.html およびhttp://utf8everywhere.org


UTF-16またはUTF-32を使用して英語以外のテキストをサポートすることになったのはなぜでしょうか。UTF-8はそれをうまく処理できます。また、英語のテキストには非ASCII文字も含まれています。ゼロ幅の非結合子のように。またはemダッシュ。申し訳ありませんが、この回答はあまり価値がありません。
IInspectable 2018

UTF-8はまだ一般的にHTMLで使用されているので、この質問は、文字の大半はUTF-8で3バイト文字であっても、ファイルdownvotingしやすいです
Ṃųỻịgǻňạcểơửṩ

@IInspectableサポートは最適な表現ではなく、宣伝するか、より良いサポートがより正確になります
robotik

utf8everywhere.orgのようなページを送信することは、私がSO回答で行うことではありません。
MichalŠtein
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.