web-dev-qa-db-ja.com

UTF-8とUnicodeの違いは何ですか

Wikipedia UTF-8 のページによると、私は人々から矛盾する意見を聞いたことがあります。

それらは同じものですね。誰かが明確にすることができますか?

430
sarsnake

他の人が与えた答えを拡大するために:

コンピュータに理想的に表示されるべき文字を多く含む言語がたくさんあります。 Unicodeは各文字に一意の番号、つまりコードポイントを割り当てます。

コンピュータはバイトのような数字を扱います。ここではちょっとした歴史を飛ばしてメモリアドレス指定の問題を無視して、8ビットコンピュータはハードウェア上で簡単に表される最大の数値単位として8ビットバイトを扱います。これは2バイトになります。

ASCIIのような古い文字エンコーディングは(前)8ビット時代からのもので、当時の計算で主流の言語、すなわち英語を0から127の範囲の数字(7ビット)に詰め込もうとしました。 )アルファベットの26文字、大文字と小文字の両方の形式、数字、句読記号で、それはかなりうまくいった。 ASCIIは、英語以外の他の言語用に8ビット拡張されていますが、この拡張によって使用可能になった追加の128個の数字/コードポイントは、表示される言語によって異なる文字にマッピングされます。 ISO-8859規格はこのマッピングの最も一般的な形式です。 ISO-8859-1およびISO-8859-15(ISO-Latin-1、latin1、およびyesとも呼ばれます)、および8859 ISO規格には2つの異なるバージョンがあります。

しかし、複数の言語の文字を表現したい場合はそれだけでは十分ではありません。そのため、使用可能なすべての文字を1バイトに圧縮するだけではうまくいきません。

基本的に2種類のエンコーディングがあります。1つはビットを追加することで値の範囲を広げるものです。これらのエンコーディングの例は、UCS2(2バイト= 16ビット)とUCS4(4バイト= 32ビット)です。たとえ限界が非常に高くても、それらの値の範囲はまだ制限されているので、それらは本質的にASCIIやISO-8859規格と同じ問題に苦しんでいます。

他のタイプのエンコーディングは1文字あたり可変数のバイトを使用します、そしてこれのための最も一般的に知られているエンコーディングはUTFエンコーディングです。すべてのUTFエンコーディングはほぼ同じ方法で機能します。Unit-8では8ビット、UTF-16では16ビット、UTF-32では32ビットの単位サイズを選択します。標準では、これらのビットのいくつかをフラグとして定義しています。それらが設定されている場合は、一連の単位の次の単位が同じ文字の一部と見なされます。設定されていない場合、この単位は完全に1文字を表します。そのため、最も一般的な(英語)文字はUTF-8では1バイト(UTF-16では2、UTF-32では4)しか占有しませんが、他の言語文字は6バイト以上を占有できます。

マルチバイトエンコーディング(上記の説明の後でマルチユニットと言います)は比較的スペース効率が良いという利点がありますが、部分文字列の検索、比較などの操作ですべて文字をUnicodeコードにデコードする必要があるという欠点があります。そのような操作を実行できるようになるまでのポイント(ただし、いくつかのショートカットがあります)。

UCS規格とUTF規格はどちらも、Unicodeで定義されているコードポイントをエンコードします。理論的には、これらのエンコーディングは(エンコーディングがサポートする範囲内で)任意の数をエンコードするために使用できます - もちろんこれらのエンコーディングはUnicodeコードポイントをエンコードするために作られました。そしてそれがあなたの関係です。

Windowsはいわゆる「Unicode」文字列をUTF-16文字列として扱いますが、最近のほとんどのUNIXではデフォルトでUTF-8が使用されています。 HTTPなどの通信プロトコルは、UTF-8の単位サイズがASCIIのものと同じであり、そのようなプロトコルのほとんどがASCII時代に設計されているため、UTF-8で最もうまく機能する傾向があります。一方、UTF-16は、すべての生きている言語を表現するときに、最高平均スペース/処理パフォーマンスを提供します。

Unicode規格では、32ビットで表現できる数より少ないコードポイントしか定義されていません。したがって、すべての実用的な目的のために、UTF-32とUCS4は同じエンコーディングになりました。これは、UTF-32でマルチユニット文字を処理する必要がないと思われるためです。

それがいくつかの詳細を埋めることを願っています。

434
unwesen

「Unicode」は、残念ながら、状況に応じてさまざまな方法で使用されます。その最も正しい使い方(IMO)は、コード化文字セット - 、つまり文字セットと文字と整数の間のマッピングとしてそれらを表すコードポイント

UTF-8 は文字エンコーディングです - バイトのシーケンスから文字のシーケンスへ、そしてその逆に変換する方法です。 Unicode文字セット全体を網羅しています。 ASCIIは1文字あたり1バイトとしてエンコードされ、他の文字はその正確なコードポイントに応じてより多くのバイトを取ります(現在定義されているすべてのコードポイントで最大4バイト、つまりU-0010FFFFまで、そして実際には4バイト)。バイトは最大U-001FFFFFまで対応可能です。

「Unicode」が文字エンコーディングの名前として使用されている場合(例:.NET Encoding.Unicode プロパティ)、通常は UTF-16 を意味します。これは、最も一般的な文字を2バイトとしてエンコードします。一部のプラットフォーム(特に.NETおよびJava)は、「ネイティブ」文字エンコーディングとしてUTF-16を使用しています。単一のUTF-16値にエンコードできない文字(「サロゲートペア」としてエンコードされている)を心配する必要がある場合、これは毛深い問題につながります - しかし、ほとんどの開発者はこれについて心配しません、IME。

Unicodeに関するいくつかの参照

189
Jon Skeet

例を使ってこのトピックを説明しましょう。

A chinese character:      汉
it's unicode value:       U+6C49
convert 6C49 to binary:   01101100 01001001

これまで魔法のようなことは何もない、それは非常に単純です。それでは、この文字をハードドライブに保存することにしたとしましょう。そのためには、文字をバイナリ形式で保存する必要があります。単に '01101100 01001001'のように保管することができます。完了しました。

しかし、ちょっと待って、 '01101100 01001001'は1文字か2文字ですか?私が言ったのであなたはこれが1文字であることを知っていました、しかしコンピュータがそれを読むとき、それは考えがありません。そのため、コンピュータにそれを1つとして扱うように指示するには、ある種の「エンコード」が必要です。

これが 'UTF-8'の規則が出てくるところです: http://www.fileformat.info/info/unicode/utf8.htm

Binary format of bytes in sequence

1st Byte    2nd Byte    3rd Byte    4th Byte    Number of Free Bits   Maximum Expressible Unicode Value
0xxxxxxx                                                7             007F hex (127)
110xxxxx    10xxxxxx                                (5+6)=11          07FF hex (2047)
1110xxxx    10xxxxxx    10xxxxxx                  (4+6+6)=16          FFFF hex (65535)
11110xxx    10xxxxxx    10xxxxxx    10xxxxxx    (3+6+6+6)=21          10FFFF hex (1,114,111)

上の表によると、 'UTF-8'フォーマットを使ってこの文字を保存したい場合は、文字の前に 'ヘッダ'を付ける必要があります。私たちの漢字は16ビットの長さ(自分でバイナリ値を数える)です、それでそれは十分なスペースを提供するので私たちは行3のフォーマットを使います:

Header  Place holder    Fill in our Binary   Result         
1110    xxxx            0110                 11100110
10      xxxxxx          110001               10110001
10      xxxxxx          001001               10001001

結果を1行に書き出す:

11100110 10110001 10001001

これは漢字のUTF-8(バイナリ)値です。 (自分で確認してください: http://www.fileformat.info/info/unicode/char/6c49/index.htm

概要

A chinese character:      汉
it's unicode value:       U+6C49
convert 6C49 to binary:   01101100 01001001
embed 6C49 as UTF-8:      11100110 10110001 10001001
181
Cheng

それらは同じものではありません - UTF-8はUnicodeをエンコードする特定の方法です。

アプリケーションと使用するデータに応じて、さまざまなエンコーディングを選択できます。私の知る限り、最も一般的なものはUTF-8、UTF-16、およびUTF-32です。

107
Greg

Unicodeはコードポイント、つまり文字を表す数値のみを定義します。これらのコードポイントをメモリに格納する方法は、使用しているエンコーディングによって異なります。 UTF-8は、とりわけUnicode文字をエンコードする1つの方法です。

60
Martin Cote

Unicodeは、ISO/IEC 10646とともに、すべてのスーパーセットであるユニバーサルキャラクタセット(UCS)を定義する規格です。既存の文字は、事実上すべての既知の言語を表すために必要です。

Unicodeは、名前と番号(文字コード、またはコードポイント)をそのレパートリーの各文字に割り当てます。

UTF-8エンコーディングは、コンピュータのメモリ内でこれらの文字をデジタルで表現する方法です。 UTF-8は各コードポイントを一連のオクテット(8ビットバイト)にマッピングします。

例えば、

UCS文字= Unicode漢字

UCSコードポイント= U + 24B62

UTF-8エンコード= F0 A4 AD A2(16進数)= 11110000 10100100 10101101 10100010(bin)

28
nightlytrails

Unicode は、文字セットを定義する単なる標準です( UCS )とエンコーディング( UTF )を使ってこの文字セットをエンコードします。しかし、一般に、Unicodeは標準ではなく文字セットに基づいています。

必ず読んでください すべてのソフトウェア開発者にとって絶対的な必要条件絶対に、確実にUnicodeと文字セットについて知っておく必要があります(言い訳はありません) および 5分でUnicode

24
Gumbo

既存の答えはすでに多くの詳細を説明しています、しかしここで最も直接的な説明と例で非常に短い答えです。

Unicodeは、文字をコードポイントにマッピングする標準です。
各文字には固有のコードポイント(識別番号)があります。これは9731のような番号です。

UTF-8は  コードポイントのエンコーディング
ディスク上のすべての文字を(ファイルに)格納するために、UTF-8は文字を最大4オクテット(8ビットのシーケンス) - バイトに分割します。 UTF-8はいくつかのエンコーディング(データを表す方法)の1つです。たとえば、Unicodeでは、(10進)コードポイント9731は、スノーマン()を表します。これは、UTF-8の3バイトで構成されています。E2 98 83

これは ソートされたリストのいくつかのランダムな例です

21
basic6

1.ユニコード

"$、&、h、a、t、?、张、1、=、+ ..."のように、世界中にたくさんの文字があります。

それからこれらの性格に専念している組織があります、

彼らは "Unicode"と呼ばれる標準を作りました。

標準は次のとおりです。

  • 各位置が「コードポイント」または「コード位置」と呼ばれるフォームを作成します。
  • 全体の位置はU + 0000からU + 10FFFFです。
  • 今までのところ、いくつかの位置は文字で埋められ、他の位置は保存されるか空になります。
  • たとえば、位置 "U + 0024"は文字 "$"で埋められます。

シモンズ:もちろん、別の標準を維持するISOと呼ばれる別の組織があります - "ISO 10646"、ほぼ同じです。

2. UTF-8

上記のように、U + 0024は単なるポジションなので、文字 "$"のためにコンピュータに "U + 0024"を保存することはできません。

エンコード方式が必要です。

それからUTF-8、UTF-16、UTF-32、UCS-2などのエンコーディング方法があります。

UTF-8では、コードポイント "U + 0024"は00100100にエンコードされます。

00100100は "$"のためにコンピュータに保存する値です。

14
wengeezhang

私はGumboの答えの中でリンクをチェックしました、そして私はStack Overflowにも存在するようにそれらのものの一部をここに貼り付けたいと思いました。

「... Unicodeは、各文字が16ビットで、したがって65,536文字の可能性がある単純な16ビットコードであるという誤解を受けている人もいます。これは実際には正しいことではありません。だから、あなたがそれを考えたのなら、気分を悪くしないでください。

実際、Unicodeでは文字についての考え方が異なります。Unicodeでの考え方について理解しておく必要があります。そうしないと意味がありません。

これまでは、文字はディスクまたはメモリに保存できるビットに対応すると想定していました。

A - > 0100 0001

Unicodeでは、文字はコードポイントと呼ばれるものにマッピングされますが、これはまだ理論上の概念です。そのコードポイントがメモリ内またはディスク上でどのように表されるかは、まったく別の話です...」

「...すべてのアルファベットのすべてのプラトン文字には、次のように書かれたUnicodeコンソーシアムによってマジックナンバーが割り当てられています。このマジックナンバーはコードポイントと呼ばれます。U+は「Unicode」を意味し、数字は16進数です。 U + 0639はアラビア語の文字Ainです。英語の文字AはU + 0041 ....になります。

「……さて、文字列があるとしましょう。

こんにちは

これは、Unicodeでは、これら5つのコードポイントに対応します。

U + 0048 U + 0065 U + 006C U + 006C U + 006F。

コードポイントがたくさんあります。数字、本当に。これをメモリに保存したり、電子メールメッセージで表現したりする方法については、まだ何も述べていません。」

「……エンコーディングが入ります.

2バイトについての神話を導いたUnicodeエンコーディングのための最も初期のアイデアは、ちょっと、ちょうど2バイトにそれらの数を格納しましょうでした。だからこんにちは

00 48 00 65 00 6C 00 6C 00 6F

右?そんなに早くない!それもできませんでした:

48 00 65 00 6C 00 6C 00 6F 00? ……」

12
kommradHomer

Unicodeは、130,000を超える文字を定義し、それぞれに数値コード(「コードポイント」)を割り当てる広範な規格です。また、このテキストのソート方法、正規化方法、大文字と小文字の変更などの規則も定義されています。 Unicodeの文字は、ゼロから0x10FFFFまでのコードポイントで表されますが、一部のコードポイントは予約されており、文字には使用できません。

Unicodeのコードは、複数のエンコードで表すことができます。最も単純なのはUTF-32です。これはコードポイントを32ビット整数として単純にエンコードします。各コードは4バイト幅です。

UTF-8は別のエンコーディングで、すぐに事実上の標準になります。バイト値のシーケンスとしてエンコードします。各コードポイントは、可変数のこれらのバイトを使用できます。 ASCII範囲のコードポイントは、ASCIIとの互換性を保つために、裸でエンコードされています。この範囲外のコードポイントは、どの範囲にあるかに応じて、2、3、または4のいずれかの可変バイト数を使用します。

UTF-8はこれらのプロパティを念頭に置いて設計されています。

  • ASCII文字は、ASCIIの場合とまったく同じようにエンコードされているため、ASCII文字列もUTF-8として有効です。

  • バイナリソート:単純なバイナリソートを使用してUTF-8文字列をソートしても、すべてのコードポイントは番号順にソートされます。

  • ASCIIの範囲外の文字は、ASCIIの範囲のバイトを使用しないため、ASCIIの文字と間違えないようになっています。これもセキュリティ機能です。

  • UTF-8は簡単に検証でき、バリデータによって他の文字エンコーディングと区別できます。他の8ビットまたはマルチバイトエンコーディングのテキストもUTF-8として検証されることはめったにありません。

  • ランダムアクセス:UTF-8文字列のどの時点でも、その位置のバイトが文字の最初のバイトであるかどうかを判断し、その文字の先頭までバックトラックすることができます。文字列の先頭.

3
thomasrutter

それらは同じものですね。

いいえ、そうではありません。


Wikipediaページ の最初の文は、ニースの簡潔な要約を与えると思います:

UTF-8は、1〜4個の8ビットバイトを使用して、Unicodeで有効なコードポイント1,112,064をすべてエンコードできる可変幅文字エンコードです。

詳しく説明するには:

  • nicodeは標準です。これは文字からマップ番号、いわゆるコードポイントを定義します(以下の例のように)。完全なマッピングについては、 here のように見えます。

    ! -> U+0021 (21),  
    " -> U+0022 (22),  
    \# -> U+0023 (23)
    
  • TF-8は、これらのコードポイントをエンコードする方法の1つコンピューターが理解できる形式、別名bitsです。言い換えると、これらのコードポイントのそれぞれをビットシーケンスに変換するか、ビットシーケンスを同等のコードポイントに変換する方法/アルゴリズムです。 Unicodeには多くの代替エンコーディングがあることに注意してください。


ジョエルは本当にすてきな説明と歴史の概要を説明します ここ

1
Dimos

このスレッドから収集した内容を要約できる場合:

Unicode '翻訳' 序数への文字(10進形式)

à = 224

UTF-8は「変換」するエンコードですこれらの数値をバイナリrepresentationsに変換します。

224 = 11000011 10100000
0
Raimi bin Karim

UTF-8は、8ビットシーケンスを使用してUnicode文字をエンコードするための方法です。

Unicodeは、さまざまな言語の多種多様な文字を表すための規格です。

0
akaMahesh