11

UnicodeのUTFについて本当に混乱しています。

UTF-8、UTF-16、UTF-32があります。

私の質問は:

  1. すべてのUnicodeブロックをサポートしているUTFは何ですか?

  2. 最高のUTF(パフォーマンス、サイズなど)とは何ですか?その理由は何ですか?

  3. これら3つのUTFの違いは何ですか?

  4. エンディアンとバイト順マーク(BOM)とは何ですか?

ありがとう

4

6 に答える 6

29

すべての Unicode ブロックをサポートする UTF は何ですか?

すべての UTF エンコーディングは、すべての Unicode ブロックをサポートします。Unicode コードポイントを表現できない UTF エンコーディングはありません。ただし、UCS-2 (UTF-16 に似ていますが、サロゲート ペアがないため、65535/U+FFFF を超えるコードポイントをエンコードする機能がない) などの一部の非 UTF の古いエンコーディングは、そうでない場合があります。

最適な UTF (パフォーマンス、サイズなど) とその理由は?

ほとんどが英語または ASCII のみのテキスト データの場合、UTF-8 が最もスペース効率が高くなります。ただし、UTF-8 は、使用されるほとんどのコードポイントが高い UTF-16 および UTF-32 よりもスペース効率が悪い場合があります (大量の CJK テキストなど)。

これら 3 つの UTF の違いは何ですか?

UTF-8 は、各 Unicode コードポイントを 1 ~ 4 バイトにエンコードします。Unicode 値 0 ~ 127 は ASCII と同じですが、ASCII と同じようにエンコードされます。値が 128 ~ 255 のバイトは、マルチバイト コードポイントに使用されます。

UTF-16 は、各 Unicode コードポイントを 2 バイト (1 つの UTF-16 値) または 4 バイト (2 つの UTF-16 値) にエンコードします。Basic Multilingual Plane (Unicode コードポイント 0 から 65535、または U+0000 から U+FFFF) のすべては、1 つの UTF-16 値でエンコードされます。より高いプレーンからのコードポイントは、「サロゲート ペア」と呼ばれる手法を通じて、2 つの UTF-16 値を使用します。

UTF-32 は Unicode の可変長エンコーディングではありません。すべての Unicode コードポイント値はそのままエンコードされます。これは、U+10FFFFとしてエンコードされることを意味し0x0010FFFFます。

エンディアンとバイト オーダー マーク (BOM) とは何ですか?

エンディアンとは、データの一部、特定の CPU アーキテクチャまたはプロトコルがマルチバイト データ型の値を順序付けする方法です。リトル エンディアン システム (x86-32 や x86-64 CPU など) は最下位バイトを最初に配置し、ビッグ エンディアン システム (ARM、PowerPC、および多くのネットワーク プロトコルなど) は最上位バイトを最初に配置します。

リトルエンディアンのエンコーディングまたはシステムでは、32 ビット値0x12345678は として保存または送信され0x78 0x56 0x34 0x12ます。ビッグエンディアンのエンコーディングまたはシステムでは、 として保存または送信され0x12 0x34 0x56 0x78ます。

UTF-16 および UTF-32 では、テキストがどのエンディアンとして解釈されるかを示すために、バイト オーダー マークが使用されます。Unicode はこれを巧妙な方法で行います。U+FEFF は有効なコードポイントであり、バイト オーダー マークに使用されますが、U+FFFE はそうではありません。したがって、ファイルが で始まる場合、ファイル0xFF 0xFEの残りの部分はリトル エンディアンのバイト順で格納されていると見なすことができます。

UTF-8 のバイト オーダー マークは技術的には可能ですが、明らかな理由から、エンディアンのコンテキストでは意味がありません。ただし、UTF-8 でエンコードされた BOM で始まるストリームは、ほぼ確実に UTF-8 であることを意味するため、識別に使用できます。

UTF-8 の利点

  • ASCII は UTF-8 エンコーディングのサブセットであるため、データ変換を行うことなく ASCII テキストを「Unicode の世界」に導入する優れた方法です。
  • UTF-8 テキストは、ASCII テキストの最もコンパクトな形式です。
  • 有効な UTF-8 はバイト値でソートでき、ソートされたコードポイントになります。

UTF-16 の利点

  • UTF-16 は可変長エンコーディングですが、UTF-8 よりもデコードが簡単です。
  • UTF-16 は、BMP 内の文字では UTF-8 よりもスペース効率が高いが、ASCII の外では

UTF-32 の利点

  • UTF-32 は可変長ではないため、デコードに特別なロジックは必要ありません
于 2011-07-30T09:41:01.110 に答える
18
于 2011-07-30T15:42:02.730 に答える
6
  1. それらはすべて、すべてのUnicodeコードポイントをサポートします。

  2. それらには異なるパフォーマンス特性があります。たとえば、UTF-8はASCII文字に対してよりコンパクトですが、UTF-32は、基本多言語面の外側(つまり、U + FFFFより上)の値を含むUnicode全体の処理を容易にします。文字ごとの幅が可変であるため、UTF-8文字列を使用してバイナリエンコーディングの特定の文字インデックスに到達するのは困難です。スキャンスルーが必要です。非BMP文字がないことがわかっている場合を除き、UTF-16についても同じことが言えます。

  3. UTF-8UTF-16UTF-32のウィキペディアの記事を見るのがおそらく最も簡単です。

  4. エンディアンネスは、(UTF-16およびUTF-32の場合)最上位バイトが最初に来て最下位バイトが最後に来るか、またはその逆かを決定します。たとえば、UTF-16でU + 1234を表す場合は、{0x12、0x34}または{0x34、0x12}のいずれかになります。バイトオーダーマークは、処理しているエンディアンを示します。UTF-8には異なるエンディアンネスはありませんが、ファイルの先頭にUTF-8 BOMが表示されていることは、それUTF-8であることを示す良い指標です。

于 2011-07-30T09:39:10.580 に答える
3

ここにいくつかの良い質問があり、すでにいくつかの良い答えがあります。何か便利なものを追加できるかもしれません。

  1. 前に述べたように、3 つすべてが可能なコードポイントの完全なセット (U+0000 から U+10FFFF) をカバーしています。

  2. 内容によって異なりますが、参考になる情報をいくつか挙げておきます。UTF-8 は 1 文字あたり 1 ~ 4 バイトを使用します。UTF-16 は 2 または 4 を使用します。UTF-32 では常に 4 が使用されます。注意すべき点はこれです。UTF-8 を使用すると、英語のテキストは大多数の文字がそれぞれ 1 バイトでエンコードされますが、中国語はそれぞれ 3 バイトが必要です。UTF-16 を使用すると、英語と中国語の両方で 2 が必要になります。したがって、基本的に UTF-8 は英語に有利です。UTF-16 は中国語の勝利です。

  3. 主な違いは、上記の #2 に対する回答に記載されているか、Jon Skeet が言うように、ウィキペディアの記事を参照してください。

  4. エンディアン: UTF-16 および UTF-32 の場合、これはバイトが表示される順序を指します。たとえば、UTF-16 では、文字 U+1234 は 12 34 (ビッグ エンディアン) または 34 12 (リトル エンディアン) としてエンコードできます。BOM、またはバイト オーダー マークは興味深いものです。UTF-16 でエンコードされたファイルがあり、ビッグ エンディアンかリトル エンディアンかはわかりませんが、ファイルの最初の 2 バイトが FE FF であることに気付いたとします。これがビッグエンディアンの場合、文字は U+FEFF になります。リトル エンディアンの場合、U+FFFE を意味します。しかし、ここに問題があります: Unicode では、コードポイント FFFE は永久に割り当てられていません:そこに文字はありません! したがって、エンコーディングはビッグエンディアンでなければならないことがわかります。ここでは、FEFF 文字は無害です。それはZERO-WIDTH NO BREAK SPACE(基本的に見えない)です。同様に、ファイルが FF FE で始まる場合、それがリトル エンディアンであることがわかります。

他の回答に何かを追加したかどうかはわかりませんが、過去に英語と中国語の具体的な分析が他の人にこれを説明するのに役立つことがわかりました。

于 2011-07-30T09:53:47.793 に答える
2

それを見る 1 つの方法は、複雑さよりもサイズです。一般に、テキストをエンコードするために必要なバイト数は増加しますが、文字を表すために使用するスキームのデコードの複雑さは減少します。したがって、UTF-8 は通常小さいですが、デコードが複雑になる可能性があります。一方、UTF-32 はより多くのバイトを消費しますが、デコードは簡単です (ただし、めったに使用されず、UTF-16 がより一般的です)。

これを念頭に置いて、UTF-8 はサイズが小さいため、ネットワーク転送によく選択されます。一方、ストレージ サイズよりも簡単なデコードが重要な場合は、UTF-16 が選択されます。

BOM は、使用されているエンコーディングを説明するファイルの先頭にある情報として意図されています。ただし、この情報はしばしば欠落しています。

于 2011-07-30T09:40:43.997 に答える
2

Joel Spolsky は Unicode についての素晴らしい入門記事を書きました:

すべてのソフトウェア開発者が絶対に、積極的に Unicode と文字セットについて知っておく必要がある絶対最小値 (言い訳はありません!)

于 2011-07-30T15:58:37.397 に答える