52

わかった。これは典型的な「なぜ彼はググったり、www.unicode.orgに行って調べたりしなかったのか?」のように見えることはわかっています。質問ですが、そのような単純な質問の場合、両方の情報源を確認した後でも答えはわかりません。

これら 3 つのエンコーディング システムはすべて Unicode 文字をすべてサポートしていると確信していますが、プレゼンテーションでそれを主張する前に確認する必要があります。

おまけの質問: これらのエンコーディングは、拡張してサポートできる文字数に違いがありますか?

4

6 に答える 6

66

あるエンコーディングに保存できるが別のエンコーディングには保存できないUnicode文字はありません。これは、有効なUnicode文字がUTF-16(3つのエンコーディングの中で最小の容量)に格納できるものに制限されているためです。つまり、UTF-8およびUTF-32は、UTF-16よりも広い範囲の文字を表すために使用できますが、そうではありません。詳細については、以下をお読みください。

UTF-8

UTF-8は可変長コードです。一部の文字は1バイトを必要とし、一部は2、一部3、および一部4を必要とします。各文字のバイトは、バイトの連続ストリームとして次々に書き込まれます。

一部のUTF-8文字は4バイト長にすることができますが、UTF-8は2^32文字をエンコードできません。それも近くではありません。その理由を説明しようと思います。

UTF-8ストリームを読み取るソフトウェアは、一連のバイトを取得するだけです。次の4バイトが1つの4バイト文字か、2つの2バイト文字か、4つの1バイト文字か(または他の組み合わせ)?基本的に、これは、特定の1バイトのシーケンスが有効な文字ではなく、特定の2バイトのシーケンスが有効な文字ではないと判断することによって行われます。これらの無効なシーケンスが表示される場合、それらはより長いシーケンスの一部を形成していると見なされます。

あなたはこれのかなり異なる例を見てきました、私は確信しています:それはエスケープと呼ばれています。多くのプログラミング言語では\、文字列のソースコード内の文字は、文字列の「コンパイル済み」形式の有効な文字に変換されないと判断されています。\nソースで\が見つかった場合、またはのような長いシーケンスの一部であると見なされます\xFF\xは無効な2文字のシーケンスであり\xF、無効な3文字のシーケンス\xFFですが、有効な4文字のシーケンスであることに注意してください。

基本的に、多くの文字を持つことと短い文字を持つことの間にはトレードオフがあります。2 ^ 32文字が必要な場合は、平均4バイトの長さである必要があります。すべての文字を2バイト以下にする場合は、2^16文字を超えることはできません。UTF-8は妥当な妥協点を提供します。すべてのASCII文字(ASCII 0〜127)には1バイトの表現が与えられます。これは互換性に優れていますが、さらに多くの文字が許可されます。

上に示した種類のエスケープシーケンスを含むほとんどの可変長エンコーディングと同様に、UTF-8は瞬時コードです。つまり、デコーダーはバイトごとに読み取り、文字の最後のバイトに到達するとすぐに、その文字が何であるかを認識します(そして、それが長い文字の始まりではないことを認識します)。

たとえば、文字「A」はバイト65を使用して表され、最初のバイトが65である2/3/4バイトの文字はありません。そうでない場合、デコーダーはこれらの文字を「A」と区別できません。 'その後に何か他のものが続きます。

しかし、UTF-8はさらに制限されています。これにより、短い文字のエンコーディングが長い文字のエンコーディング内のどこにも表示されないことが保証されます。たとえば、4バイト文字のどのバイトも65にすることはできません。

UTF-8には128個の異なる1バイト文字(バイト値は0〜127)があるため、2、3、および4バイト文字はすべて128〜256の範囲のバイトのみで構成する必要があります。それは大きな制限です。ただし、バイト指向の文字列関数をほとんどまたはまったく変更せずに機能させることができます。たとえば、Cのstrstr()関数は、その入力が有効なUTF-8文字列である場合、常に期待どおりに機能します。

UTF-16

UTF-16も可変長コードです。その文字は2バイトまたは4バイトを消費します。0xD800-0xDFFFの範囲の2バイト値は、4バイト文字を作成するために予約されており、すべての4バイト文字は、0xD800-0xDBFFの範囲の2バイトと、それに続く0xDC00-0xDFFFの範囲の2バイトで構成されます。このため、UnicodeはU + D800-U+DFFFの範囲の文字を割り当てません。

UTF-32

UTF-32は固定長のコードで、各文字の長さは4バイトです。これにより、2 ^ 32の異なる文字のエンコードが可能になりますが、このスキームでは0〜0x10FFFFの値のみが許可されます。

容量の比較:

  • UTF-8: 2,097,152(実際には2,166,912ですが、設計の詳細により、一部は同じものにマップされます)
  • UTF-16: 1,112,064
  • UTF-32: 4,294,967,296(ただし、最初の1,114,112に制限されます)

したがって、最も制限されているのはUTF-16です。正式なUnicode定義では、Unicode文字はUTF-16でエンコードできる文字に制限されています(つまり、U+D800からU+DFFFを除くU+0000からU+10FFFFの範囲)。UTF-8およびUTF-32は、これらすべての文字をサポートしています。

UTF-8システムは、実際には「人為的に」4バイトに制限されています。前に概説した制限に違反することなく8バイトに拡張でき、これにより2^42の容量が得られます。元のUTF-8仕様では、実際には最大6バイトが許可されていたため、容量は2^31になります。しかし、RFC 3629はそれを4バイトに制限しました。これは、UTF-16が行うすべてのことをカバーするために必要な量だからです。

他の(主に歴史的な)Unicodeエンコーディングスキーム、特にUCS-2(U+0000からU+FFFFまでしかエンコードできない)があります。

于 2008-11-11T06:42:25.853 に答える
45

いいえ、それらは単に異なるエンコード方法です。それらはすべて、同じ文字セットのエンコードをサポートしています。

UTF-8 は、エンコードする文字に応じて、1 文字あたり 1 ~ 4 バイトを使用します。ASCII 範囲内の文字は 1 バイトしか使用しませんが、非常に特殊な文字は 4 バイト使用します。

UTF-32 は、文字に関係なく 1 文字あたり 4 バイトを使用するため、同じ文字列をエンコードするために常に UTF-8 よりも多くのスペースを使用します。唯一の利点は、バイトをカウントするだけで UTF-32 文字列の文字数を計算できることです。

UTF-16 では、ほとんどの文字に 2 バイトを使用し、特殊な文字には 4 バイトを使用します。

http://en.wikipedia.org/wiki/Comparison_of_Unicode_encodings

于 2008-09-24T23:04:26.293 に答える
7

UTF-8、UTF-16、および UTF-32 はすべて、Unicode コード ポイントの完全なセットをサポートします。ある文字でサポートされていても、別の文字ではサポートされていない文字はありません。

おまけの質問については、「これらのエンコーディングは、サポートするために拡張できる文字数が異なりますか?」はいといいえ。UTF-8 と UTF-16 のエンコード方法により、サポートできるコード ポイントの総数が 2^32 未満に制限されます。ただし、Unicode コンソーシアムは、UTF-8 または UTF-16 で表現できないコード ポイントを UTF-32 に追加しません。これを行うと、エンコーディング標準の精神に違反し、UTF-32 から UTF-8 (または UTF-16) への 1 対 1 のマッピングを保証できなくなります。

于 2008-09-24T23:00:06.600 に答える
5

個人的には、Unicode、エンコーディング、および文字セットについて疑問がある場合は、常にJoel の投稿をチェックしています。

于 2008-09-24T22:55:47.407 に答える
4

すべての UTF-8/16/32 エンコーディングは、すべての Unicode 文字をマップできます。ウィキペディアの Unicode エンコーディングの比較 を参照してください。

この IBM の記事Encode your XML documents in UTF-8は非常に役に立ち、選択肢がある場合は UTF-8 を選択することをお勧めします。主な理由は幅広いツールのサポートであり、UTF-8 は通常、Unicode を認識しないシステムを通過できます。

IBMの記事仕様の内容セクションから:

最近、W3C と IETF の両方が、UTF-8 を最初、最後、場合によっては 1 つだけ選択することに固執するようになりました。W3C Character Model for the World Wide Web 1.0: Fundamentals には、「一意の文字エンコーディングが必要な場合、文字エンコーディングは UTF-8、UTF-16、または UTF-32 でなければなりません。US-ASCII は UTF との上位互換性があります。 8 (US-ASCII 文字列も UTF-8 文字列です。[RFC 3629] を参照してください)、したがって、US-ASCII との互換性が必要な場合は UTF-8 が適切です。" 実際には、US-ASCII との互換性は非常に便利であり、ほぼ必須です。W3C は賢明にも次のように説明しています。

于 2008-09-24T23:13:35.820 に答える
2

誰もが言っているように、UTF-8、UTF-16、および UTF-32 はすべて、すべての Unicode コード ポイントをエンコードできます。ただし、UCS-2 (誤って UCS-16 と呼ばれることもあります) バリアントはできません。これは、Windows XP/Vista などで見られるものです。

詳細については、ウィキペディアを参照してください。

編集: Windows については間違っています。UCS-2 をサポートするのは NT だけでした。ただし、多くの Windows アプリケーションは、UCS-2 のようにコード ポイントごとに 1 つの単語を想定するため、バグが見つかる可能性があります。別のウィキペディアの記事を参照してください。(ジェイソントゥルーに感謝)

于 2008-09-25T02:18:25.627 に答える