UTF-8の「可変幅エンコーディング」はどのように機能しますか?


110

ユニコード標準には、それらをすべて格納するために4バイトが必要となる十分なコードポイントが含まれています。これは、UTF-32エンコーディングが行うことです。しかし、UTF-8エンコーディングは、「可変幅エンコーディング」と呼ばれるものを使用して、これらを何らかの方法ではるかに小さなスペースに圧縮します。

実際、US-ASCIIの最初の127文字を実際のASCIIのように見えるちょうど1バイトで表すことができるので、何もしなくても多くのASCIIテキストをUTF-8であるかのように解釈できます。きちんとしたトリック。それはどのように機能するのでしょうか?

私はここで自分の質問をし、それに答えるつもりです。なぜなら、それを理解するために少し読んだだけで、誰かが時間を節約できると思ったからです。それに、もし私がそれのいくつかを間違っているなら、誰かが私を訂正してくれるかもしれません。


8
Straight Unicodeは、すべてのコードポイントをエンコードするために32ビットを必要としませ。彼らはかつて多くの可能なコードポイントを主張していましたが、UTF-8が離陸した後、彼らは意図的に21ビットに制限したため、UTF-8は1文字あたり4バイトを超えません。Unicodeは現在、すべての可能なコードポイントを保持するのに17ビットしか必要としません。この制限がない場合、UTF-8は1文字あたり6バイトになりました。
ウォーレンヤング

@ウォーレン:ほとんど正確ですが、Unicodeは21ビットコードです(U + 0000からU + 10FFFF)。
ジョナサンレフラー、

2
@ウォーレン:4バイト制限のUTF-8は、U + 1FFFFFまでサポートできました。U + 10FFFFへの制限は、UTF-16のために行われました。
dan04

@ dan04 UTF-16によってU + 10FFFFに制限される方法について簡単な説明はありますか?これについてもっと知りたいと思います。
A-letubby 2016

@ A-letubby:1024個の先行サロゲートと1024個の証跡サロゲート(およびペアでのみ使用可能)が存在するようにUTF-16の「サロゲート」コードが割り当てられるため、2 ^ 20(約100万)の追加文字を作成します。 BMPを超えて利用可能。BMPで使用可能な2 ^ 16文字に追加され、これにより0x110000の文字が可能になります。
dan04 2016

回答:


129

各バイトは、それがシングルバイトコードポイント、マルチバイトコードポイント、またはマルチバイトコードポイントの継続であるかどうかを示す数ビットで始まります。このような:

0xxx xxxx    A single-byte US-ASCII code (from the first 127 characters)

マルチバイトのコードポイントはそれぞれ、基本的に「私が何であるかを理解するために次のバイト(または2つまたは3つ)も読み取る必要がある」と言う数ビットで始まります。彼らです:

110x xxxx    One more byte follows
1110 xxxx    Two more bytes follow
1111 0xxx    Three more bytes follow

最後に、これらの開始コードに続くバイトはすべて次のようになります。

10xx xxxx    A continuation of one of the multi-byte characters

最初の数ビットからどのバイトの種類を見ているかがわかるので、どこかで何かが壊れたとしても、シーケンス全体を失うことはありません。


14
ストーリーにはそれ以上のものがあります-エンコーディングは文字の可能な最短のエンコーディングでなければならないため、たとえばバイト0xC0と0xC1はUTF-8で表示できないことを意味します。そして実際には、どちらも0xF5..0xFFはできません。unicode.org/faq/utf_bom.htmlまたはunicode.org/versions/Unicode5.2.0/ch03.pdf
Jonathan Leffler

2
なぜ1つの文字だけを使用して言うことができないのnext char is continuationですか?3バイトの文字を取得すると、のよう1xxxxxxx 1xxxxxxx 0xxxxxxxになるため、無駄になるスペースが少なくなります。

9
@Soakuは、UTF-8をいわゆる「自己同期」コードにします。これは、エラーのためにシーケンスの一部が欠落している場合、それを検出し、文字化けしたものをすべて破棄することが可能であることを意味します。10xxで始まるバイトを読み取り、先行する「開始」バイトがない場合は、意味がないので破棄できます。説明したようなシステムがあり、最初のバイトの1つが失われた場合、エラーの種類を示さずに、別の有効な文字になる可能性があります。また、次の有効な文字を見つけやすくなり、欠落している「継続」バイトを修正できます。
htmlcoderexe '12

9

RFC3629-UTF-8、ISO 10646の変換フォーマットは、ここでの最終的な権限であり、すべての説明があります。

要するに、単一の文字を表すUTF-8エンコードの1から4バイトのシーケンスの各バイトのいくつかのビットは、それが後続バイトであるか、先行バイトであるかを示し、そうである場合はその後に続くバイト数を示します。残りのビットにはペイロードが含まれています。


1
うーん、ばかげた私は、Unicode標準がUTF-8の最終的な権威であると思った
John Machin

6
Unicode標準は、Unicode自体を定義します。さまざまな目的(ストレージやトランスポートなど)でUnicodeテキストをエンコードするために使用できる、現在および将来のさまざまなメソッドを定義していません。UTF-8はそれらのメソッドの1つであり、上記の参照はそれを定義するドキュメントへの参照です。
azheglov、2010

1
RFC3629の3ページのセクション3には、「UTF-8はUnicode規格で定義されている」と記載されています。
John Machin 2017年

unicode.orgのリンクをたどると、Unicode標準のセクション3.9に移動し、特にD92(および接線方向にD86)を定義しました。新しいバージョンがリリースされたときに、このリンクがどの程度役立つかはわかりませんが、バージョン間でセクションと定義の識別子を安定させておきたいと思っています。
Tripleee、2018年

4

UTF-8は、8ビットバイトを使用してUnicodeコードポイントの文字列、つまり魔法のU +番号をメモリに格納するためのもう1つのシステムです。UTF-8では、0〜127のすべてのコードポイントが1バイトに格納されます。128以上のコードポイントのみが、2、3、実際には最大6バイトを使用して保存されます。

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


これは良い記事ですが、ジョエルはシーケンスの最大長に関して間違っているようです。ウィキペディアのページには、1文字あたり1..4バイトのみが表示されます。
アンワインド

4
上記で述べたように、UTF-8が最初に作成されたとき、Unicodeは、コードポイントに対して最大32ビットを要求しました。32ビットは便利な値であり、すでにそれを超えているためです。以前の16ビット文字の制限。UTF-8の人気が証明された後、彼らはコードポイントの最大数を2 ^ 21に永久に制限することを選択しました。これは、UTF-8スキームの4バイトでエンコードできる最大値です。Unicodeの文字数は2 ^ 17未満であるため、この新しいスキームを使用すると、Unicodeの文字数を4倍以上にすることができます。
ウォーレンヤング

OKですが、OPからの説明ではありません。
Nishant 2014

2
これは質問に対する答えではありません。
Koray Tugay
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.