web-dev-qa-db-ja.com

UTF-8とUTF-16の違いは?

UTF-8とUTF-16の違いは?なぜこれらが必要なのですか?

MessageDigest md = MessageDigest.getInstance("SHA-256");
String text = "This is some text";

md.update(text.getBytes("UTF-8")); // Change this to "UTF-16" if needed
byte[] digest = md.digest();
132
theJava

これについてはWebの周りに多くの良い記事があると思いますが、ここに短い要約があります。

UTF-8とUTF-16はどちらも可変長エンコーディングです。ただし、UTF-8では文字は最低8ビットを占めることがありますが、UTF-16では文字の長さは16ビットで始まります。

主なUTF-8の長所:

  • 数字のような基本的なASCII文字、アクセントのないラテン文字などは、US-ASCII表現と同一の1バイトを占有します。このようにして、すべてのUS-ASCII文字列が有効なUTF-8になり、多くの場合、適切な後方互換性が提供されます。
  • ヌルで終わる文字列を使用できるヌルバイトなし。これにより、後方互換性も大幅に向上します。
  • UTF-8はバイトオーダーに依存しないため、ビッグエンディアン/リトルエンディアンの問題を心配する必要はありません。

主なUTF-8の短所:

  • 一般的な文字の多くは長さが異なるため、コードポイントによるインデックス作成とコードポイントカウントの計算が非常に遅くなります。
  • バイトオーダーは重要ではありませんが、テキストがUTF-8でエンコードされていることを通知するのに役立つBOM(バイトオーダーマーク)がUTF-8に含まれている場合があります。また、ASCIIテキストにはASCII文字のみが含まれます。 Microsoftソフトウェア(メモ帳など)は、特にBOMをUTF-8に追加することを好みます。

主なUTF-16の長所:

  • ラテン語、キリル文字、ほとんどの中国語(PRCはBMP以外のコードポイントを必須にした)を含むBMP(基本多言語面)文字、ほとんどの日本語は2バイトで表現できます。これにより、テキストにnotに補助文字が含まれる場合のインデックス作成とコードポイントカウントの計算が高速化されます。
  • テキストに補助文字がある場合でも、16ビット値のペアで表されます。つまり、合計の長さは2で割り切れ、16ビットcharを文字列のプリミティブコンポーネントとして使用できます。 。

主なUTF-16の短所:

  • US-ASCII文字列に大量のnullバイトがあります。これは、nullで終了する文字列がなく、大量のメモリが浪費されることを意味します。
  • 多くの一般的なシナリオ(特に米国/ EU /キリル文字のある国/イスラエル/アラブ諸国/イランなど)で固定長エンコードとして使用すると、ほとんど機能しません。 これは、プログラマーがサロゲートペアを認識し、重要な場合に適切に処理する必要があることを意味します!
  • これは可変長であるため、コードポイントのカウントまたはインデックス作成はコストがかかりますが、UTF-8よりも小さくなります。

一般に、UTF-16は、BE/LEが無関係で(ネイティブの順序を使用するだけ)、インデックス作成が高速であるため(サロゲートペアを適切に処理することを忘れないでください)、メモリ内表現に適しています。一方、UTF-8は、BE/LEの問題がなく、ヌル終了がASCII互換性と同様に便利であるため、テキストファイルおよびネットワークプロトコルに非常に適しています。

278
Sergei Tachenov

それらは、Unicode文字を表現するための単なる異なるスキームです。

両方とも可変長です-UTF-16は、一般的に使用されるほとんどの文字を含む基本的な多言語面(BMP)のすべての文字に2バイトを使用します。

UTF-8は、BMPの文字に1〜3バイト、U + 0000〜U + 1FFFFFの現在のUnicode範囲の文字に最大4バイトを使用し、それが必要になった場合に最大U + 7FFFFFFFに拡張可能です...ただし、すべてのASCII文字は、それぞれ1バイトで表されます。

メッセージダイジェストの目的のために、ダイジェストを再作成しようとするすべての人が同じオプションを使用する限り、これらのどれを選択してもかまいません。

UTF-8およびUnicodeの詳細については、 このページ を参照してください。

(すべてのJava文字はBMP内のUTF-16コードポイントであることに注意してください。U+ FFFFより上の文字を表すには、Javaでサロゲートペアを使用する必要があります。)

18
Jon Skeet

これはUTF-8/16とは無関係です(一般に、UTF16に変換され、BE/LE部分は1行で設定できます)が、以下はStringをbyte []に​​変換する最も速い方法です。たとえば、提供されたケースにぴったりです(ハッシュコード)。 String.getBytes(enc)は比較的遅いです。

static byte[] toBytes(String s){
        byte[] b=new byte[s.length()*2];
        ByteBuffer.wrap(b).asCharBuffer().put(s);
        return b;
    }
4
bestsss

セキュリティ:UTF-8のみを使用

UTF-8とUTF-16の違いは?なぜこれらが必要なのですか?

TF-16 の実装には、少なくとも2つのセキュリティ脆弱性があります。 詳細についてはウィキペディア を参照してください。

WHATWGW3C現在宣言済み のみ TF-8 がWebで使用されることを意味します。

ここで概説した[セキュリティ]の問題は、UTF-8を排他的に使用することで解消されます。これは、現在すべてのものの必須のエンコードである多くの理由の1つです。

他のグループも同じことを言っています。

したがって、UTF-16はJavaやWindowsなどの一部のシステムで引き続き内部的に使用される場合がありますが、データファイルやデータ交換などで過去に見たUTF-16の使用はほとんどありません。おそらく完全に消えてしまいます。

0
Basil Bourque