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();
これについてはWebの周りにたくさんの良い記事があると思いますが、ここに短い要約があります。
UTF-8とUTF-16はどちらも可変長エンコーディングです。ただし、UTF-8では、文字は最低8ビットを占める場合がありますが、UTF-16では、文字の長さは16ビットで始まります。
UTF-8の主な長所:
主なUTF-8の短所:
UTF-16の主な長所:
char
、文字列のプリミティブコンポーネントとして16ビットを使用できます。主なUTF-16の短所:
一般に、UTF-16は通常、メモリ内表現に適しています。これは、BE / LEはそこでは無関係であり(ネイティブの順序を使用するだけ)、インデックス作成が高速であるためです(サロゲートペアを適切に処理することを忘れないでください)。一方、UTF-8は、BE / LEの問題がなく、ASCII互換性だけでなく、null終端が役立つことが多いため、テキストファイルやネットワークプロトコルに非常に適しています。
これらは、Unicode文字を表すための単純に異なるスキームです。
どちらも可変長です-UTF-16は、一般的に使用されるほとんどの文字を含む基本的な多言語平面(BMP)のすべての文字に2バイトを使用します。
UTF-8は、BMPの文字に1〜3バイト、現在のUnicode範囲のU + 0000〜U + 1FFFFFの文字に最大4バイトを使用し、必要に応じてU+7FFFFFFFまで拡張可能です...ただし、特にすべてのASCII文字はそれぞれ1バイトで表されます。
メッセージダイジェストの目的では、ダイジェストを再作成しようとするすべての人が同じオプションを使用する限り、これらのどれを選択してもかまいません。
UTF-8とUnicodeの詳細については、このページを参照してください。
(すべてのJava文字はBMP内のUTF-16コードポイントであることに注意してください。U+ FFFFより上の文字を表すには、Javaでサロゲートペアを使用する必要があります。)
UTF-8とUTF-16の違いは?なぜこれらが必要なのですか?
UTF-16の実装には、少なくとも2つのセキュリティの脆弱性があります。詳細については、ウィキペディアを参照してください。
WHATWGとW3Cは、 UTF-8のみをWebで使用することを宣言しました。
ここで概説した[セキュリティ]の問題は、UTF-8を排他的に使用すると解消されます。これは、現在すべてのものに必須のエンコーディングとなっている多くの理由の1つです。
他のグループも同じことを言っています。
したがって、UTF-16はJavaやWindowsなどの一部のシステムで内部的に使用され続ける可能性がありますが、データファイルやデータ交換などで過去に見たUTF-16の使用は、完全になくなる可能性があります。
これは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;
}
UTF-8とUTF-16を区別する簡単な方法は、それらの間の共通点を特定することです。
特定の文字に対して同じUnicode番号を共有することを除いて、それぞれが独自の形式です。
UTF-8は、文字に指定されたすべてのUnicode番号を1バイト(ASCIIの場合)、2 2バイト、4バイトなどで表現しようとします。
UTF-16は、最初に2バイトの文字に与えられたすべてのUnicode番号を表現しようとします。2バイトでは不十分な場合は、4バイトを使用します。それでも不十分な場合は、6バイトを使用します。
理論的には、UTF-16の方がスペース効率が高くなりますが、実際には、処理する文字のほとんど(データの98%)がASCIIであり、UTF-8はそれらを1バイトとUTF-16で表現しようとするため、UTF-8の方がスペース効率が高くなります。それらを2バイトで表現してみてください。
また、UTF-8はASCIIエンコーディングのスーパーセットです。したがって、ASCIIデータを期待するすべてのアプリはUTF-8プロセッサでも受け入れられます。これはUTF-16には当てはまりません。UTF-16はASCIIを理解できませんでした。これは、UTF-16を採用する上での大きなハードルです。
もう1つの注意点は、現時点ですべてのUNICODEが最大4バイトのUTF-8に収まる可能性があることです(世界のすべての言語を考慮)。これはUTF-16と同じであり、UTF-8(https://stackoverflow.com/a/8505038/3343801)と比較して実際にスペースを節約することはできません。
したがって、人々は可能な限りUTF-8を使用します。