web-dev-qa-db-ja.com

UTF-16のポイントは何ですか?

UTF-16エンコーディングのポイントを理解したことがありません。文字列をランダムアクセスとして扱う必要がある場合(つまり、コードポイントがコード単位と同じである場合)、UTF-16は可変長であるため、UTF-32が必要です。これが不要な場合、UTF-16はUTF-8に比べてスペースの巨大な無駄のように見えます。 UTF-8とUTF-32に対するUTF-16の利点は何ですか?なぜWindowsとJavaをネイティブエンコーディングとして使用するのですか?

67
dsimcha

Windows NTが設計されたとき、UTF-16は存在しませんでした(NT 3.51は1993年に生まれましたが、UTF-16は1996年にUnicode 2.0標準で生まれました)。代わりに、当時はUnicodeで利用可能なすべての文字を保持するのに十分なUCS-2がありました。そのため、1コードポイント= 1コードユニットの等価性は実際には真でした-文字列に可変長ロジックは必要ありません。

Unicode文字セット全体をサポートするために、後でUTF-16に移行しました。ただし、UTF-8またはUTF-32に移行することはできませんでした。これは、APIインターフェース(特に)のバイナリ互換性が失われるためです。

Javaについては、よくわかりません。 〜1995年にリリースされて以来、UTF-16はすでに標準化されていないと思われますが、NTベースのオペレーティングシステムとの互換性が選択に何らかの役割を果たした可能性があると思います(継続的) Windows APIを呼び出すたびにUTF-8 <-> UTF-16変換を行うと、処理が遅くなる場合があります)。


編集

ウィキペディアは、Javaについても同じように機能しました。元々はUCS-2をサポートしていましたが、J2SE 5.0ではUTF-16に移行しました。

したがって、一般に、一部のAPI /フレームワークでUTF-16が使用されているのは、それがUCS-2として開始されたためです(文字列管理アルゴリズムの複雑化を避けるため)が、UTF-16に移動して、 BMP、同じコードユニットサイズを維持。

47
Matteo Italia

UTF-8に対するUTF-16の利点を示す応答は、後方互換性の応答を除いて、意味がありません。

さて、私のコメントには2つの警告があります。

Erikは次のように述べています。「UTF-16は、BMPを単一の単位でカバーします-したがって、BMPの外のよりまれな文字が必要でない限り、UTF-16は1文字あたり2バイトです。」

警告1)

アプリケーションがBMP外の文字を一切必要とせず、BMP外で文字を必要とするアプリケーションでそれを使用するために作成したライブラリコードが決して使用されないことが確実な場合は、 UTF-16、およびすべての文字がちょうど2バイトの長さであるという暗黙の仮定を行うコードを記述します。

それは非常に危険なようです(実際には、愚かです)。

コードがすべてのUTF-16文字の長さが2バイトであると想定し、プログラムがBMPの外に単一の文字があるアプリケーションまたはライブラリと対話する場合、コードは壊れます。 UTF-16を検査または操作するコードは、2バイト以上を必要とするUTF-16文字のケースを処理するように作成する必要があります。したがって、私はこの警告を「却下」しています。

UTF-16は、UTF-8よりもコード化が簡単ではありません(両方のコードは可変長文字を処理する必要があります)。

警告2)

UTF-16は、適切に記述されている場合、状況によっては計算効率が向上する可能性があります。

このように:特定の長い文字列はめったに変更されないが、頻繁に検査されると仮定します(または、より良い、作成後never変更-つまり、変更不可能な文字列を作成する文字列ビルダー)。各文字列にフラグを設定して、文字列に「固定長」の文字のみが含まれている(つまり、長さがちょうど2バイトではない文字が含まれていない)かどうかを示すことができます。フラグがtrueである文字列は、固定長(2バイト)文字を想定する最適化されたコードで調べることができます。

スペース効率はどうですか?

UTF-16は明らかに、A)UTF-8よりもエンコードするのに必要なバイト数が少ない文字に対して、より効率的です。

UTF-8は、明らかに、B)UTF-8よりもエンコードに必要なバイト数が少ない文字のほうが効率的です。

非常に「特殊な」テキストを除いて、count(B)がcount(A)をはるかに超える可能性があります。

19
user3162129

UTF-16は [〜#〜] bmp [〜#〜] 全体を単一の単位でカバーします-したがって、BMPの外のよりまれな文字が必要でない限り、UTF-16は事実上2バイトキャラクター。 UTF-32はより多くのスペースを必要とし、UTF-8は可変長サポートを必要とします。

3
Erik

UTF16は通常、マルチバイト文字セットへの直接マッピングとして使用されます。つまり、元の0-0xFFFFに割り当てられた文字をオンにします。

これは両方の長所を提供します。文字サイズは固定されていますが、だれでも使用する可能性のあるすべての文字を印刷できます(正統的なクリンゴンの宗教的なスクリプトを除く)

1
Martin Beckett

UTF-16では、すべての基本的な多言語プレーン(BMP)を単一のコード単位として表すことができます。 U + FFFFを超えるUnicodeコードポイントは、サロゲートペアで表されます。

興味深いのは、JavaおよびWindows(およびUTF-16を使用する他のシステム)はすべて、Unicodeコードポイントレベルではなく、コードユニットレベルで動作することです。したがって、単一の文字で構成される文字列U + 1D122(MUSICAL SYMBOL F CLEF)はJava as "\ ud824\udd22" and "\ud824\udd22".length() == 2(not 1)。つまり、一種のハックですが、文字は可変長ではないことがわかりました。

UTF-8よりもUTF-16が優れている点は、UTF-8で同じハックが使用された場合、諦めすぎてしまうことです。

1
Ted Hopp