1. ホーム
  2. java

[解決済み] UTF-8とUTF-16の違い?

2022-05-10 03:29:21

質問

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();

どのように解決するのですか?

このことについては、ウェブ上にたくさんの良い記事があると思いますが、ここでは簡単にまとめてみました。

UTF-8 と UTF-16 はどちらも可変長エンコーディングです。しかし、UTF-8 では 1 文字が最低 8 ビットを占有するのに対し、UTF-16 では文字長は 16 ビットから始まります。

UTF-8の主な長所。

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

UTF-8 の主な短所。

  • 多くの共通文字が異なる長さを持つため、コードポイントによるインデックス作成とコードポイント数の計算が恐ろしく遅くなります。
  • バイトオーダーが重要でないにもかかわらず、UTF-8 には BOM (byte order mark) が残っていることがあります。これは、テキストが UTF-8 でエンコードされていることを知らせる役割を果たし、テキストに ASCII 文字しか含まれていなくても、ASCII ソフトウェアとの互換性を破壊してしまいます。Microsoft ソフトウェア (メモ帳など) は特に、UTF-8 に BOM を追加したがります。

UTF-16 の主な長所。

  • ラテン語、キリル文字、ほとんどの中国語 (PRC は BMP 以外のいくつかのコードポイントのサポートを必須にしました)、ほとんどの日本語を含む BMP (basic multilingual plane) 文字は、2 バイトで表現することができます。これにより、インデックス作成と、テキストが ではない がない場合、インデックス作成とコードポイント数の計算が高速化されます。
  • テキストに補足文字が含まれていても、それらは 16 ビット値のペアで表現されるため、全長はまだ 2 で割り切れることになり、16 ビット char を文字列のプリミティブ成分として使用することができます。

UTF-16の主成分。

  • US-ASCII 文字列の多くのヌルバイト、これはヌル終端文字列がなく、多くのメモリが無駄になることを意味します。
  • 固定長エンコーディングとして使用すると、多くの一般的なシナリオ (特に米国/EU/キリル文字の国/イスラエル/アラブ諸国/イランなど) で「ほとんど機能」し、そうでない場所では壊れたサポートになることがよくあります。 つまり、プログラマはサロゲートペアを認識し、それが重要である場合には適切に処理しなければならないのです!
  • 可変長なので、UTF-8よりは少ないですが、コードポイントのカウントやインデックス付けはコストがかかります。

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