web-dev-qa-db-ja.com

Javaの「サロゲートペア」とは何ですか?

StringBufferのドキュメント、特に reverse() メソッドを読んでいました。そのドキュメントには、サロゲートペアについての何かが記載されています。このコンテキストでのサロゲートペアとは何ですか?そして、lowおよびhigh代理変数とは何ですか?

135
Raymond

「サロゲートペア」という用語は、UTF-16エンコードスキームで高いコードポイントを持つUnicode文字をエンコードする手段を指します。

Unicode文字エンコードでは、文字は0x0〜0x10FFFFの値にマップされます。

内部的に、JavaはUTF-16エンコーディングスキームを使用してUnicodeテキストの文字列を格納します。UTF-16では、16ビット(2バイト)コード単位が使用されます。 0x0から0xFFFFまでの文字の範囲、この範囲(0x10000から0x10FFFF)を超える値を格納するために追加の複雑さが使用されますこれは、サロゲートと呼ばれるコード単位のペアを使用して行われます。

サロゲートコード単位は、2コード単位シーケンスの開始または終了で許可されるかどうかに応じて、「高サロゲート」と「低サロゲート」として知られる2つの範囲にあります。

115

Early Javaバージョンは16ビットcharデータ型を使用してUnicode文字を表しました。すべてのUnicode文字の値は65,535(0xFFFF)未満で16で表現できるため、この設計は当時意味がありました。ただし、後でUnicodeは最大値を1,114,111(0x10FFFF)に増やしました.16ビット値はUnicodeバージョン3.1のすべてのUnicode文字を表すには小さすぎたため、32ビット値(コードポイントと呼ばれる)が採用されましたUTF-32エンコーディングスキームしかし、効率的なメモリ使用のために32ビット値よりも16ビット値が優先されるため、Unicodeは16ビット値の継続使用を可能にする新しい設計を導入しました。エンコードスキームは、1,024の値を16ビットの上位サロゲート(U + D800からU + DBFFの範囲)に割り当て、別の1,024の値を16ビットの下位サロゲート(U + DC00からU + DFFFの範囲)に割り当てます。 (1,024と1,024の積)1,0を表すために、上位サロゲートの後に下位サロゲート(サロゲートペア)が続きます65,536(0x10000)から1,114,111(0x10FFFF)までの48,576(0x100000)の値。

44
ibrahem shabban

そのドキュメントが言っていることは、無効なUTF-16文字列は有効な文字列の逆である可能性があるため、reverseメソッドを呼び出した後に有効になる可能性があるということです。サロゲートペア(説明済み ここ )は、単一のUnicodeコードポイントをエンコードするUTF-16の16ビット値のペアです。低いサロゲートと高いサロゲートは、そのエンコーディングの半分です。

22

this postから上記の回答にさらに情報を追加する

Java-12でテスト済み。すべてのJavaバージョン5以上で動作するはずです。

ここで言及したように: https://stackoverflow.com/a/47505451/2987755
いずれかの文字(UnicodeがU + FFFFより上にあるもの)は、サロゲートペアとして表されます。これはJava char値のペアとして格納されます。つまり、単一のUnicode文字は2隣接するJava文字。
次の例でわかるように。
1。長さ:

_"????".length()  //2, Expectations was it should return 1

"????".codePointCount(0,"????".length())  //1, To get number of Unicode character in Java String  
_

2.平等:
「????」を表します以下のようにUnicode _\ud83c\udf09_を使用して文字列に変換し、同等であることを確認します。

_"????".equals("\ud83c\udf09") // true
_

JavaはUTF-32をサポートしていません

_"????".equals("\u1F309") // false  
_

3. Unicode文字をJava Stringに変換できます

_"????".equals(new String(Character.toChars(0x0001F309))) //true
_

4. String.substring()は、補助文字を考慮しません

_"????????".substring(0,1) //"?"
"????????".substring(0,2) //"????"
"????????".substring(0,4) //"????????"
_

これを解決するには、String.offsetByCodePoints(int index, int codePointOffset)を使用できます

_"????????".substring(0,"????????".offsetByCodePoints(0,1) // "????"
"????????".substring(2,"????????".offsetByCodePoints(1,2)) // "????"
_

5. BreakIterator を使用したUnicode文字列の反復
6。 Unicodeを使用した文字列のソート Java.text.Collat​​or
7。文字を大文字、小文字は使用しないでください。代わりに、特定のロケールの大文字と小文字の文字列を使用してください
8。 Character.isLetter(char ch)はサポートされていません。より適切に使用されるCharacter.isLetter(int codePoint)、Characterクラスの各methodName(char ch)メソッドには、処理できるmethodName(int codePoint)のタイプがあります。補助文字。
9。 String.getBytes()で文字セットを指定し、BytesからString、InputStreamReaderOutputStreamWriterに変換します

参照:
https://coolsymbol.com/emojis/emoji-for-copy-and-paste.html#objects
https://www.online-toolz.com/tools/text-unicode-entities-convertor.php
https://www.ibm.com/developerworks/library/j-unicode/index.html
https://www.Oracle.com/technetwork/articles/javaee/supplementary-142654.html

例の詳細 image1image2
探索する価値のある他の用語: 正規化BiDi

7
dkb

サロゲートペアは、特定の文字をエンコードするUTF-16の方法を参照します。 http://en.wikipedia.org/wiki/UTF-16/UCS-2#Code_points_U.2B10000..U.2B10FFFF

6
dfb

サロゲートペアは、1つの「コードポイント」を構成するUTF-16の2つの「コードユニット」です。 Javaドキュメンテーションは、これらの「コードポイント」は有効であり、「コードユニット」は逆順に正しく順序付けられていることを述べています。有効なサロゲートペアを形成します。つまり、ペアになっていないコードユニットがある場合、逆の逆が同じではない可能性があります。

ただし、ドキュメントでは、複数のコードポイントを組み合わせたGraphemesについては何も言及していないことに注意してください。つまり、eとそれに付随するアクセントはまだ切り替えられる可能性があるため、eの前にアクセントを配置します。つまり、eの前に別の母音がある場合、eにあったアクセントが得られる可能性があります。

うわぁ!

3
Gerard ONeill

小さな序文

  • Unicodeはコードポイントを表します。各コードポイントは、Unicode標準に従って8、16、または32ビットブロックでエンコードできます。
  • バージョン3.1以前は、UTF-8として知られている8ビットのエンコードと、UCS-2または「2オクテットでコード化されたユニバーサル文字セット」として知られている16ビットのエンコードが主に使用されていました。 UTF-8はUnicodeポイントを1バイトブロックのシーケンスとしてエンコードしますが、UCS-2は常に2バイトを使用します。

    A = 41-UTF-8の8ビットの1ブロック
    A = 0041-UCS-2を使用した16ビットの1ブロック
    Ω= CE A9-UTF-8の8ビットの2ブロック
    Ω= 03A9-UCS-2の16ビットの1ブロック

問題

コンソーシアムは、2 ^ 16 = 65536可能性のあるコード値を与える、人間が読み取れる言語をカバーするには16ビットで十分だと考えました。これは、BPMまたはBasic Multilingual Planeとしても知られるPlane 0にも当てはまり、現在では65536コードポイントのうち55,445が含まれています。 BPMは、中日韓記号(CJK)を含む、世界中のほぼすべての人間の言語をカバーしています。

時間が経ち、新しいアジアの文字セットが追加され、中国のシンボルだけで70,000ポイント以上かかりました。現在、標準の一部として 絵文字ポイント があります。新しい16の「追加」 飛行機 が追加されました。 UCS-2の部屋は、Plane-0より大きいものをカバーするには不十分でした。

Unicodeの決定

  1. Unicodeを17プレーンに制限します。プレーンあたり65 536文字= 1 114 112最大ポイント。
  2. 各コードポイントに32ビットを保持し、すべてのプレーンをカバーするために、以前はUCS-4として知られていたUTF-32を提示します。
  3. ダイナミックエンコーディングとしてUTF-8を引き続き使用し、UTF-8を各コードポイントで最大4バイトに制限します。つまり、ポイントあたり1〜4バイトに制限します。
  4. UCS-2の廃止
  5. UCS-2に基づいてUTF-16を作成します。 UTF-16を動的にすると、ポイントごとに2バイトまたは4バイトかかります。 High Surrogatesと呼ばれる1024ポイントU + D800–U + DBFFをUTF-16に割り当てます。低サロゲートと呼ばれる1024個のシンボルU + DC00–U + DFFFをUTF-16に割り当てます。

    これらの変更により、BPMはUTF-16の16ビットの1ブロックでカバーされますが、すべての「補助文字」は2ブロックを示すサロゲートペアでカバーされます16ビットずつ、合計1024x1024 = 1 048 576ポイント。

    高サロゲートが低サロゲートに先行する。この規則からの逸脱は、エンコーディングの不良と見なされます。たとえば、ペアのないサロゲートは正しくありません。低いサロゲートは高いサロゲートの前に立っています。

    ????、「MUSICAL SYMBOL G CLEF」は、サロゲートのペア0xD834 0xDD1E(2 x 2バイト)としてUTF-16でエンコードされます。
    UTF-8で0xF0 0x9D 0x84 0x9E(4 x 1バイト)、
    UTF-32で0x0001D11E(1 x 4バイト)。

現在の状況

  • 標準に従ってサロゲートは特にUTF-16にのみ割り当てられますが、歴史的には一部のWindowsおよびJavaアプリケーションはサロゲート範囲に予約されているUTF-8およびUCS-2ポイントを使用していました。
    UTF-8/UTF-16エンコーディングが正しくないレガシーアプリケーションをサポートするために、新しい標準 WTF-8 のWobbly Transformation Formatが作成されました。ペアではないサロゲートや不正なシーケンスなど、任意のサロゲートポイントをサポートします。今日、一部の製品は標準に準拠せず、UTF-8をWTF-8として扱います。
  • 代理ソリューションは、異なるエンコーディング間の変換において多くの セキュリティ問題 を開き、それらのほとんどは適切に処理されました。

トピックfollowに従うために、多くの歴史的な詳細が抑制されました。
最新のUnicode標準は http://www.unicode.org/versions/latest にあります。

0
Artru