Unicodeの基礎とは何か、なぜUTF-8またはUTF-16が必要なのか?私はこれをグーグルで研究し、ここでも検索しましたが、私にはわかりません。
VSSでファイル比較を行うと、2つのファイルのUTFが異なるというメッセージが表示されることがあります。なぜこれが当てはまるのでしょうか?
簡単に説明してください。
Unicodeの基礎とは何か、なぜUTF-8またはUTF-16が必要なのか?私はこれをグーグルで研究し、ここでも検索しましたが、私にはわかりません。
VSSでファイル比較を行うと、2つのファイルのUTFが異なるというメッセージが表示されることがあります。なぜこれが当てはまるのでしょうか?
簡単に説明してください。
回答:
(それほどではないが)初期には、存在するのはASCIIだけでした。これは問題ではありませんでした。必要なのは、この文にあるようないくつかの制御文字、句読点、数字、および文字だけでした。残念ながら、今日の世界的な相互通信とソーシャルメディアの奇妙な世界は予見されておらず、英語、العربية、汉语、עִבְרִית、ε、λληνικά、およびភាសាខ្មែរを同じドキュメントに表示することも珍しくありません(私は古いものを壊していないといいのですが)ブラウザ)。
しかし、議論のために、ジョー・アベレージはソフトウェア開発者だとしましょう。彼は英語しか必要ないので、ASCIIだけを使いたいと主張しています。これはユーザーのジョーにとっては問題ないかもしれませんが、ソフトウェア開発者のジョーにとっては問題ではありません。世界の約半分が非ラテン文字を使用しており、ASCIIを使用することは間違いなくこれらの人々に無関心であり、さらにその上、彼はソフトウェアを大規模で成長している経済に締めくくっています。
したがって、すべての言語を含む包括的な文字セットが必要です。したがって、Unicodeが登場しました。すべての文字にコードポイントと呼ばれる一意の番号を割り当てます。他の可能なセットに対するUnicodeの利点の1つは、最初の256個のコードポイントがISO-8859-1と同一であるため、ASCIIであることです。さらに、一般的に使用される文字の大部分は、Basic Multilingual Plane(BMP)と呼ばれる領域で、2バイトのみで表現できます。この文字セットにアクセスするには文字エンコードが必要です。質問のとおり、UTF-8とUTF-16に集中します。
では、これらのエンコーディングのどの文字にアクセスできるバイトがいくつあるのでしょうか。
BMPに含まれていない文字には、古代の文字、数学記号、音楽記号、および珍しい中国語/日本語/韓国語(CJK)文字が含まれることをここで言及する価値があります。
主にASCII文字で作業する場合は、UTF-8の方がメモリ効率が高いことは確かです。ただし、主にヨーロッパ以外のスクリプトで作業している場合、UTF-8を使用すると、UTF-16の最大1.5分の1のメモリ効率で済みます。大きなWebページや長いWord文書など、大量のテキストを処理する場合、これはパフォーマンスに影響を与える可能性があります。
注:UTF-8およびUTF-16のエンコード方法がわかっている場合は、実用的なアプリケーションについて次のセクションに進んでください。
1
、ASCII文字との衝突を避けるためのものです。見てわかるように、UTF-8とUTF-16は互いにほとんど互換性がありません。したがって、I / Oを実行している場合は、使用しているエンコーディングを確認してください。これらのエンコーディングの詳細については、UTF FAQを参照してください。
文字データ型と文字列データ型:プログラミング言語でどのようにエンコードされていますか?それらが生のバイトである場合、非ASCII文字を出力しようとする瞬間に、いくつかの問題が発生する可能性があります。また、文字タイプがUTFに基づいている場合でも、文字列が適切なUTFであるとは限りません。不正なバイトシーケンスを許可する場合があります。一般に、C、C ++、Java用のICUなど、UTFをサポートするライブラリを使用する必要があります。いずれにしても、デフォルトのエンコーディング以外のものを入力/出力したい場合は、最初にそれを変換する必要があります。
推奨/デフォルト/主要なエンコーディング:使用するUTFを選択する場合、通常は作業している環境の推奨標準に従うことが最適です。たとえば、WebではUTF-8が主要であり、HTML5以降はされている推奨のエンコーディング。逆に、.NETとJavaの両方の環境は、UTF-16文字タイプに基づいています。混乱して(そして誤って)、「Unicodeエンコーディング」への参照がよく行われます。これは通常、特定の環境での主要なUTFエンコーディングを指します。
ライブラリサポート:使用しているライブラリは、ある種のエンコーディングをサポートしています。どれ?コーナーケースをサポートしていますか?必要性は発明の母であるので、UTF-8ライブラリーは一般に4バイト文字を適切にサポートします。1、2、さらには3バイト文字が頻繁に発生する可能性があるためです。ただし、サロゲートペアが非常にまれにしか発生しないため、サロゲートペアが適切にサポートされているとは限りません。
文字を数える:存在し組み合わせる文字はUnicodeで。たとえば、コードポイントU + 006E(n)、およびU + 0303(チルドの組み合わせ)はñを形成しますが、コードポイントU + 00F1はñを形成します。それらは同一に見えるはずですが、単純なカウントアルゴリズムは最初の例では2を返し、後者の例では1を返します。これは必ずしも間違っているわけではありませんが、望ましい結果ではない場合もあります。
同等性の比較: A、А、およびΑは同じように見えますが、それぞれラテン語、キリル語、ギリシャ語です。Cやlikeのようなケースもあります。1つは文字で、もう1つはローマ数字です。さらに、考慮すべき結合文字もあります。詳細については、Unicodeでの重複文字を参照してください。
サロゲートペア:これらはSOで頻繁に表示されるため、リンクの例をいくつか示します。
その他?:
Unicodeはかなり複雑な標準です。恐れる必要はありませんが、仕事に備えましょう。[2]
信頼できるリソースは常に必要ですが、公式レポートは膨大であるため、以下を読むことをお勧めします。
簡単な説明:
コンピュータはバイトを読み取り、人々は文字を読み取るため、エンコーディング標準を使用して文字をバイトにマッピングします。ASCIIは最初に広く使用された標準でしたが、ラテン語のみをカバーしています(7ビット/文字は128の異なる文字を表すことができます)。Unicodeは、世界のすべての可能な文字をカバーすることを目標とした標準です(最大1,114,112文字を保持できます。つまり、最大21ビット/文字です。現在のUnicode 8.0は、合計で120,737文字を指定しています。それだけです)。
主な違いは、ASCII文字はバイト(8ビット)に適合しますが、ほとんどのUnicode文字は適合しないことです。したがって、エンコーディングフォーム/スキーム(UTF-8やUTF-16など)が使用され、文字モデルは次のようになります。
すべての文字は、コードポイントと呼ばれる0から1,114,111(16進数:0-10FFFF)までの列挙された位置を保持します。エンコード形式は、コード単位配列にコードポイントをマッピングします。コード単位は、あなたは文字がメモリ、8ビット単位、16ビット単位で編成され、その上になりたい方法です。UTF-8は1〜4ユニットの8ビットを使用し、UTF-16は1または2ユニットの16ビットを使用して、最大21ビットのUnicode全体をカバーします。ユニットは接頭辞を使用して文字の境界を見つけることができます。ユニットが多いほど、ビットを占有する接頭辞が多くなります。したがって、UTF-8はラテン文字のスクリプトに1バイトを使用しますが、基本多言語プレーン内の以降のスクリプトには3バイトが必要ですが、UTF-16はこれらすべてに2バイトを使用します。そして、それが主な違いです。
最後に、コード化スキーム
(UTF-16BEまたはUTF-16LEのように)コードユニットシーケンスをバイトシーケンスにマップ(シリアル化)します。
文字:π
コードポイント:U + 03C0
エンコード形式(コード単位):
UTF-8:CF 80
UTF-16:03C0
エンコードスキーム(バイト):
UTF-8:CF 80
UTF-16BE:03 C0
UTF-16LE:C0 03
ヒント:16進数は4ビットを表すため、2桁の16進数はバイトを表します。
また、Wikipediaの平面マップを見て、文字セットレイアウトの感触をつかんでください。
もともと、Unicodeは固定幅16ビットエンコーディング(UCS-2)を持つことを目的としていました。JavaやWindows NTのようなUnicodeの初期の採用者は、16ビット文字列を中心にライブラリを構築しました。
その後、Unicodeの範囲が拡張され、16ビットエンコーディングがサポートする65,536以上のコードポイントが必要になる履歴文字が含まれるようになりました。UCS-2を使用していたプラットフォームで追加の文字を表現できるようにするために、UTF-16エンコーディングが導入されました。「サロゲートペア」を使用して、補助平面の文字を表します。
一方、多くの古いソフトウェアとネットワークプロトコルは8ビット文字列を使用していました。これらのシステムがワイド文字を使用せずにUnicodeをサポートできるように、UTF-8が作成されました。7ビットASCIIとの下位互換性があります。
この記事はすべての詳細を説明します http://kunststube.net/encoding/
バッファへの書き込み
4バイトのバッファ、あ
UTF8エンコーディングのシンボルに書き込むと、バイナリは次のようになります。
00000000 11100011 10000001 10000010
4バイトのバッファ、あ
UTF16エンコーディングのシンボルに書き込むと、バイナリは次のようになります。
00000000 00000000 00110000 01000010
ご覧のとおり、コンテンツで使用する言語に応じて、これはメモリに影響を与えます。
たとえば、この特定のシンボルの場合:あ
次のシンボルに使用する2つの予備バイトがあるため、UTF16エンコーディングはより効率的です。ただし、日本のアルファベットにUTF16を使用する必要があるという意味ではありません。
バッファーからの読み取り
ここで、上記のバイトを読み取る場合は、書き込まれたエンコーディングを確認し、正しくデコードする必要があります。
たとえば、これを00000000 11100011 10000001 10000010
をUTF16エンコーディングにデコード
すると、最終的に臣
はあ
注:エンコードとUnicodeは2つの異なるものです。Unicodeは大きな(テーブル)であり、各シンボルは一意のコードポイントにマッピングされています。たとえば、あ
シンボル(文字)には(コードポイント):30 42(16進数)があります。一方、エンコーディングは、ハードウェアに保存するときに、シンボルをより適切な方法に変換するアルゴリズムです。
30 42 (hex) - > UTF8 encoding - > E3 81 82 (hex), which is above result in binary.
30 42 (hex) - > UTF16 encoding - > 30 42 (hex), which is above result in binary.
Unicodeは、すべての言語の文字をコードポイントと呼ばれる特定の数値にマッピングする標準です。これを行う理由は、同じコードポイントのセットを使用して異なるエンコーディングを可能にするためです。
UTF-8とUTF-16はそのような2つのエンコーディングです。それらはコードポイントを入力として受け取り、明確に定義された数式を使用してコード化して、エンコードされた文字列を生成します。
特定のエンコーディングの選択は、要件によって異なります。エンコーディングによってメモリ要件は異なります。処理する文字に応じて、バイトのシーケンスが最も少ないエンコーディングを選択して、それらの文字をエンコードする必要があります。
Unicode、UTF-8、UTF-16の詳細については、この記事をチェックしてください。
なぜユニコードなのか?ASCIIは127文字しかないためです。128から255までは国によって異なるため、コードページがあります。つまり、最大1114111文字まで使用できるとのことです。では、どのようにして最高のコードポイントを格納しますか?21ビットを使用して保存する必要があるため、32ビットのDWORDと11ビットの無駄を使用します。したがって、DWORDを使用してUnicode文字を格納する場合、DWORDの値がコードポイントと正確に一致するため、これが最も簡単な方法です。ただし、DWORD配列はもちろんWORD配列よりも大きく、BYTE配列よりもさらに大きくなります。そのため、utf-32だけでなくutf-16も存在します。しかし、utf-16はWORDストリームを意味し、WORDは16ビットなので、最高のコードポイント1114111をWORDにどのように適合させることができますか?できない!したがって、彼らは65535を超えるすべてのものをDWORDに入れ、サロゲートペアと呼びます。このようなサロゲートペアは2つのワードであり、最初の6ビットを調べることで検出できます。では、utf-8はどうでしょうか?これはバイト配列またはバイトストリームですが、最高のコードポイント1114111をバイトにどのように合わせることができますか?できない!さて、彼らはDWORDも入れましたよね?それとも言葉でしょうか?ほぼ正解です。彼らはutf-8シーケンスを発明しました。つまり、127を超えるすべてのコードポイントは、2バイト、3バイト、または4バイトのシーケンスにエンコードされる必要があります。うわー!しかし、どうすればそのようなシーケンスを検出できますか?まあ、127まではすべてASCIIで、1バイトです。110で始まるものは2バイトシーケンス、1110で始まるものは3バイトシーケンス、11110で始まるものは4バイトシーケンスです。これらのいわゆる「スタートバイト」の残りのビットは、コードポイントに属します。シーケンスに応じて、次のバイトが続く必要があります。次のバイトは10で始まります 残りのビットは6ビットのペイロードビットで、コードポイントに属しています。スタートバイトとそれに続くバイトのペイロードビットを連結すると、コードポイントが得られます。これがutf-8の魔法です。
ASCII-ソフトウェアは、特定の文字に対してメモリ内の8ビットバイトのみを割り当てます。これは、対応する10進数値が10進数値で128未満になるため、英語および採用された(ファサードのような借用語)文字に適しています。Cプログラムの例。
UTF-8-ソフトウェアは、指定された文字に1〜4個の可変8ビットバイトを割り当てます。ここで変数とはどういう意味ですか?ブラウザのHTMLページ(HTMLはUTF-8)を介して文字「A」を送信しているとしましょう。対応する10進数のAは65で、10進数に変換すると01000010になります。これには1バイトしか必要ありません。 、単語ファサードの「ç」のような特別に採用された英語の文字にも1バイトのメモリが割り当てられます。ただし、ヨーロッパ言語の文字を格納する場合は2バイトが必要なので、UTF-8が必要です。ただし、アジア言語の文字を使用する場合は、最小2バイト、最大4バイトが必要です。同様に、絵文字には3〜4バイトが必要です。UTF-8はすべてのニーズを解決します。
UTF-16は、文字あたり最小2バイト、最大4バイトを割り当てます。1バイトまたは3バイトは割り当てません。各文字は、16ビットまたは32ビットで表されます。
では、なぜUTF-16が存在するのでしょうか。元々、Unicodeは8ビットではなく16ビットでした。Javaは元のバージョンのUTF-16を採用しました。
簡単に言えば、作業中の言語またはプラットフォームですでにUTF-16が採用されていない限り、UTF-16は必要ありません。
Webブラウザーによって呼び出されるJavaプログラムはUTF-16を使用しますが、WebブラウザーはUTF-8を使用して文字を送信します。
UTFは、Unicode Transformation Formatの略です。基本的に、今日の世界では、他の何百もの言語で記述されたスクリプトがあり、以前に使用された基本的なASCIIではカバーされていません。したがって、UTFが誕生しました。
UTF-8には文字エンコード機能があり、そのコード単位は8ビットですが、UTF-16の場合は16ビットです。