UTF-8でエンコードできる文字数はいくつですか?


97

UTF-8が8ビットの場合、最大256の異なる文字しか存在できないという意味ではありませんか?

最初の128コードポイントはASCIIと同じです。しかし、UTF-8は最大100万文字をサポートできると言っていますか?

これはどのように作動しますか?


2
すべての答えが間違っているので、この質問を再評価してください。私の回答をお読みください:stackoverflow.com/a/45042566/124486
Evan Carroll

UnicodeのUTF-8、UTF-16、UTF-32エンコーディングでは、数値はそのコード単位のビット数であり、その1つ以上がUnicodeコードポイントをエンコードします。
トムブロジェット2017年

1
私はしばらく前にこの質問に答えて正直しようとしました:物語全体を伝えていない文字通りの単一のウィキペディアの引用である選択された回答と比較するといいでしょう(うまくいけば私の更新より明確です)
エヴァンキャロル

回答:


135

UTF-8は常に1バイトを使用するのではなく、1〜4バイトです。

最初の128文字(US-ASCII)には1バイトが必要です。

次の1,920文字をエンコードするには、2バイトが必要です。これは、ほとんどすべてのラテン文字のアルファベットの残りと、ギリシャ語、キリル文字、コプト語、アルメニア語、ヘブライ語、アラビア語、シリア語、トーナ語のアルファベット、およびダイアクリティカルマークの組み合わせをカバーしています。

残りのBasic Multilingual Planeの文字には、3バイトが必要です。これには、ほとんどの中国語、日本語、韓国語の[CJK]文字を含む、一般的に使用されるほとんどすべての文字が含まれています[12]。

Unicodeの他のプレーンの文字には4バイトが必要です。これには、あまり一般的ではないCJK文字、さまざまな履歴スクリプト、数学記号、絵文字(絵文字)が含まれます。

ソース:ウィキペディア


こんにちは@zwippie私はこれが初めてです。取得できないものがあります。BMPは2バイトを使用しますが、3バイトですか?私が間違っている?
chiperortiz

1
@ chiperortiz、BMPは確かに16ビットであるため、文字ごとに一定の長さのUTF-16としてエンコードできます(UTF-16は16ビットを超えることもサポートしていますが、これは難しい慣行であり、多くの実装ではサポートされていません)。ただし、UTF-8の場合は、その長さもエンコードする必要があるため、一部のビットが失われます。これが、完全なBMPをエンコードするために3バイトが必要な理由です。これは無駄に見えるかもしれませんが、UTF-16は常に2バイトを使用しますが、UTF-8はほとんどのラテン語ベースの言語文字に対して1文字あたり1バイトを使用することを覚えておいてください。2倍のコンパクト化。
sanderd17

OPの質問の主な目的は、なぜそれがUTF - 8と呼ばれているのかに関係しています-これは実際には答えません。
jbyrd

39

UTF-8は、文字あたり1〜4バイトを使用します。ASCII文字の場合は1バイトです(最初の128個のUnicode値はasciiと同じです)。ただし、必要なのは7ビットだけです。最上位(「符号」)ビットが設定されている場合、これはマルチバイトシーケンスの開始を示します。設定された連続する上位ビットの数はバイト数を示し、次に0になり、残りのビットは値に影響します。他のバイトの場合、最上位の2ビットは1と0で、残りの6ビットは値用です。

したがって、4バイトのシーケンスは11110 ...(および... =値の3ビット)で始まり、次に値がそれぞれ6ビットの3バイトで、21ビットの値になります。2 ^ 21はUnicode文字の数を超えているため、すべてのUnicodeをUTF8で表現できます。


@NickL。いいえ、3バイトを意味します。その例では、マルチバイトシーケンスの最初のバイトが1111で始まる場合、最初の1はそれマルチバイトシーケンスの始まりであることを示し、その後の連続する1の数はシーケンス内の追加のバイト数を示します(つまり、最初の1バイトは110、1110、または11110のいずれかで始まります)。
CodeClown42

RFC 3629であなたの言葉の証拠が見つかりました。tools.ietf.org / html / rfc3629 # section -3。しかし、なぜ2番目のバイトの先頭に「10」を配置する必要があるのか​​わかりません110xxxxx 10xxxxxx?なぜ110xxxxx xxxxxxxxだけではないのですか?
kolobok

3
softwareengineering.stackexchange.com/questions/262227/…で回答が見つかりました。安全上の理由から(ストリームの中央の1バイトが破損している場合)
kolobok

@kolobokああ。安全ではなく、21ビットの値を3バイトでエンコードできます(長さを示す3ビットに21ビットを加えたもの)。:Dおそらくそれはそれほど意味がありませんが、少なくともWRT西洋言語では。
CodeClown42 2017年

NickLがこれを尋ねたと思いますが、...がビットではなく後続のバイトを表す場合、その最初のバイトの残りのビットはどうなりましたか?
c6754

26

この表によると UTF-8 は以下をサポートする必要があります。

2 31 = 2,147,483,648文字

ただし、RFC 3629では可能な値が制限されていたため、4バイトに制限されているため、

2 21 = 2,097,152文字

これらの文字の適切なチャンクは、カスタム使用のために「予約」されていることに注意してください。これは、実際にはアイコンフォントにとって非常に便利です。

*使用されているウィキペディアは6バイトのテーブルを表示します-彼らはそれ以来記事を更新しました。

2017-07-11:複数のバイトでエンコードされた同じコードポイントを二重にカウントするように修正


この答えは、可能なエンコードの数を二重に数えています。2 ^ 7をすべて数えたら、2 ^ 11、2 ^ 16などでそれらを再び数えることはできません。可能なエンコーディングの正しい数は2 ^ 21です(現在すべてが使用されているわけではありません)。
ジミー

@ジミーあなたは私が二重に数えていると確信していますか?0xxxxxxx7つの使用可能なビットを110xxxxx 10xxxxxx与え、さらに11を与えます-重複はありません。最初のバイト0は最初のケースで始まり1、2番目のケースで始まります。
mpen 2017年

@mpenでは、どのコードポイントが00000001格納され、何が11000000 100000001格納されるのでしょうか。
エヴァンキャロル

1
@EvanCarroll Uhh ....ポイントが取れました。同じコードポイントをエンコードする方法が複数あることに気づかなかった。
mpen 2017

1
:私は先にあなたがこの質問へのより良い説明と答えだと思うかどうかを確認し、自分自身をこれを答えることを試み行ってきましたstackoverflow.com/a/45042566/124486
エヴァンキャロル

21

UnicodeとUTF-8

Unicodeはコードポイントを文字に解決します。UTF-8はUnicodeのストレージメカニズムです。Unicodeには仕様があります。UTF-8には仕様があります。どちらにも制限があります。UTF-8には別の上限があります。

Unicode

Unicodeは「プレーン」で指定されます。各飛行機は2 16コードポイントを運びます。Unicodeには17のプレーンがあります。合計17 * 2^16コードポイント。第一の平面、プレーン0またはBMPは、それが運ぶものの重量に特殊です。

すべてのニュアンスを説明するのではなく、飛行機に関する上記の記事を引用します。

17面は1,114,112コードポイントを収容できます。これらのうち、2,048は代理であり、66は非文字であり、137,468は私的使用のために予約されており、974,530は公開割り当て用に残されています。

UTF-8

さて、上にリンクされた記事に戻りましょう。

UTF-8で使用されるエンコード方式は、2 31コードポイント(32,768プレーン)のはるかに大きな制限で設計されており、4バイトに制限されていても2 21コードポイント(32プレーン)をエンコードできます。[3] UnicodeではコードポイントがUTF-16でエンコードできる17プレーンに制限されているため、0x10FFFFを超えるコードポイントはUTF-8およびUTF-32では無効です。

したがって、有効なUnicodeではないものをUTF-8に入れることができることがわかります。どうして?UTF-8は、Unicodeでさえサポートされていないコードポイントに対応しているためです。

UTF-8は、4バイトの制限があっても、2 21コードポイントをサポートします。これは、17 * 2^16


18

2,164,864の「文字」は、UTF-8で潜在的にコード化できます。

この数は2 ^ 7 + 2 ^ 11 + 2 ^ 16 + 2 ^ 21であり、エンコーディングの動作方法に由来します。

  • 1バイト文字にはエンコード用に7ビット 0xxxxxxx(0x00-0x7F)があります

  • 2バイト文字には、エンコード用に11ビットがあります 110xxxxx 10xxxxxx(最初のバイトは0xC0-0xDF、2番目のバイトは0x80-0xBF)

  • 3バイト文字にはエンコード用に16ビットがあります 1110xxxx 10xxxxxx 10xxxxxx(最初のバイトは0xE0-0xEF、継続バイトは0x80-0xBF)

  • 4バイト文字には、エンコード用に21ビットがあります 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx(最初のバイトは0xF0-0xF7、継続バイトは0x80-0xBF)

ご覧のとおり、これは現在のUnicode(1,112,064文字)よりも大幅に大きくなっています。

更新

追加のルールを考慮していないため、最初の計算は間違っています。詳細については、この回答へのコメントを参照してください。


2
計算では、コードポイントをエンコードできるのは最短のコードユニットシーケンスのみであるというUTF-8ルールは考慮されません。したがって、00000001はU + 0001に対して有効ですが、11110000 10000000 10000000 10000001は無効です。参照:表3-7。整形式のUTF-8バイトシーケンス。さらに、質問は表によって直接回答されます。範囲を合計するだけです。(それらは、UTF-16のサロゲートを除外するためにばらばらです)。
トムブロジェット2017年

トム-コメントありがとうございます!私はそれらの制限を知りませんでした。私は表3-7を見て、数値実行しましたが、有効なシーケンスが1,083,392ありそうです。
ルーベンレイエス

6

UTF-8は、1文字あたり最低 8ビットの可変長エンコーディングです。 より高いコードポイントを持つ文字は、最大32ビットかかります。


2
これは誤解を招くものです。持つことができる最長のコードポイントは11110xxx 10xxxxxx 10xxxxxx 10xxxxxxなので、実際の文字のエンコードに使用できるのは21ビットだけです。
ボリス

5
コードポイントのエンコードには最大32ビットかかる可能性があると述べましたが、(誘導により)2 ^ 32文字を32ビットUTF-8でエンコードできるとは決して主張しませんでした。しかし、既存のすべてのUnicode文字をUTF-8でエンコードでき、UTF-8を48ビット(存在するが非推奨)にストレッチするとさらにエンコードできるため、これはかなりおもしろくないので、誤解を招くポイントです。
だます


2

Unicode標準と、FAQエントリ、UTF-8、UTF-16、UTF-32、BOMなどの関連情報を確認してください。これはスムーズな航海ではありませんが、信頼できる情報であり、他の場所でUTF-8について読む可能性のあることの多くには疑問があります。

「UTF-8」の「8」は、コード単位の長さをビットで表したものです。コード単位は、文字をエンコードするために使用されるエンティティであり、必ずしも単純な1対1のマッピングとしてではありません。UTF-8は、可変数のコード単位を使用して文字をエンコードします。

UTF-8でエンコードできる文字のコレクションは、UTF-16またはUTF-32の場合とまったく同じです。つまり、すべてのUnicode文字です。これらはすべて、Unicodeコーディングスペース全体をエンコードします。これには、非文字や未割り当てのコードポイントも含まれます。


1

現在の最大UTF-8コード(2,164,864)についてmpenに同意しますが(以下にリストし、彼にはコメントできません)、UTF-8の2つの主要な制限(4バイトのみ)を削除すると、彼は2レベルオフになります制限とコード254および255は使用できません(彼は4バイトの制限を削除しただけです)。

開始コード254は、開始ビット(1に設定されたマルチビットフラグ、6の1のカウント、およびターミナル0、スペアビットなし)の基本配置に従い、(6 10xxxxxxグループ、追加の2 ^ 36コード)。

開始コード255は基本設定に厳密に従っていません。ターミナル0はありませんが、すべてのビットが使用され、追加の7バイト(1に設定されたマルチビットフラグ、7の1のカウント、およびすべてのビットが使用されるためターミナル0はありません) ; 7 10xxxxxxグループ、追加の2 ^ 42コード)。

これらを追加すると、最終的に表示可能な最大文字セットは4,468,982,745,216になります。これは、現在使用されているすべての文字、古い言語または使用されていない言語、および失われたと考えられている言語よりも多いものです。天使や天体のスクリプトは誰ですか?

また、254および255に加えて、UTF-8標準で見落とされたり無視されたりするシングルバイトコード(128-191、およびその他いくつか)があります。一部はキーボードでローカルに使用され、サンプルコード128は通常削除バックスペースです。他の開始コード(および関連する範囲)は、1つ以上の理由で無効です(https://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences)。


0

UnicodeはUTF-8と固く結びついています。Unicodeは2 ^ 21コードポイント(2,097,152文字)を具体的にサポートしています。これは、UTF-8でサポートされるコードポイントの数とまったく同じです。どちらのシステムも同じ「デッド​​」スペースとコードポイントなどの制限ゾーンを予約しています。... 2018年6月現在、最新バージョンのUnicode 11.0には137,439文字のレパートリーが含まれています

ユニコード標準から。 Unicode FAQ

Unicode規格は、21ビットのコード空間に相当するU + 0000..U + 10FFFFの範囲の文字をエンコードします。

UTF-8 Wikipediaページから。 UTF-8の説明

2003年にUnicodeコードスペースが21ビット値に制限されたため、UTF-8はコードポイントを1〜4バイトにエンコードするように定義されています...


21ビットは切り上げられます。Unicodeは、言われているように1,114,112コードポイント(U + 0000からU + 10FFFF)をサポートします。(時々、65536の17の平面として記述されます。)
トム・ブロジェット

@TomBlodget、あなたは正しいです。この議論から最も重要なポイントは、UTF-8がUnicode標準で現在定義されているすべてのポイントをエンコードできることであり、かなり長い間そうすることができるでしょう。
表示名
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.