あるエンコーディングに保存できるが別のエンコーディングには保存できない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までしかエンコードできない)があります。