2

文字が占めるバイト数を決定するために、UTF-16 バイト ストリームを読み取るためのルールは何ですか? 私は標準を読みましたが、実際の UTF-16 でエンコードされたストリームの経験的な観察に基づいて、標準が当てはまらない場所があるようです (または、私が見逃している標準の側面があります)。 .

UTF-16 標準の読み取りからhttps://www.rfc-editor.org/rfc/rfc2781 :

先頭 2 バイトの値 結果の文字長 (バイト)
0x0000-0xC7FF 2
0xD800-0xDBFF 4
0xDC00-0xDFFF 無効なシーケンス (RFC2781 2.2.2)
0xDFFF-0xFFFF 4

実際には、少なくとも一部のケースでは、これが当てはまるようです。アドホック SQL スクリプト (SQL Server 2019; UTF-16 照合順序) を使用しますが、オンライン デコーダーでも検証されます。

キャラクター ユニコード名 ISO10646 UTF-16 エンコード (16 進数、ビッグ エンディアン) サイズ (バイト)
ラテン大文字 A U+0041 00 41 2
Б キリル大文字BE U+0411 04 11 2
ァ</td> カタカナ小文字A U+30A1 30 A1 2
うさぎの顔 U+1F430 D8 3D DC 30 4

ただし、次の ISO 10646 文字を UTF-16 にエンコードすると、4 バイトのように見えますが、先頭の 2 バイトを読み取っても、これほど長いかどうかはわかりません。

キャラクター ユニコード名 UTF-16 エンコード (16 進数、ビッグ エンディアン) サイズ (バイト)
⚕️ アスクレピオスの杖 26 95 FE 0F 4

私は質問をソフトウェアにとらわれないようにしたいと思います。次の SQL は、既定の照合順序と既定の言語を使用して、Microsoft SQL Server 2019 でこの動作を再現します。(SQL Server はリトル エンディアンであることに注意してください)。

select cast(N'⚕️' as varbinary);
----------
0x95260FFE

簡単に言えば、「このキャラクターの次の単語を読む必要がある」とどのように/なぜ0x2695考えますか? これが公開された UTF-16 標準と一致していないように見えるのはなぜですか?

4

2 に答える 2

1

あなたの主張はすべて完全に正しいです。あなたの UTF-16 標準の解釈は正しく、完全です。

ただし、経験的な観察では、キャラクターは 1 つしかないと想定しています。実際には、Unicode 実装のニュアンスに出くわしました。あなたの「キャラクター」は実際には2つです(技術的には視覚的ではありませんが):U+2695 "STAFF OF AESCULAPIUS"に続いてU+FE0F "VARIATION SELECTOR-16"。2 番目の文字は、文字バリアントをレンダリングする目的で基本文字と結合する非スペーシング マークです。

これにより、バイト シーケンス26 95 FE 0Fが生成されますが、どちらの単語も UTF-16 の予約済み拡張文字範囲に含まれないことに注意してください。しかし、これはどちらも UTF-16 4 バイト拡張子を必要としないためです。それらは、2 つの別個の Unicode 文字として単純に分類されます。

ISO 10646の7.9 Combining Marks : Universal Coded Character Set (UCS)から:,

結合マークは、ベースと呼ばれる前の文字と結合することを目的とした Unicode 標準の文字の特別なクラスです。

結合マークは通常、目に見えるグリフ形式を持っています...結合マークは、さまざまな方法で隣接する文字とグラフィカルに相互作用する場合があります。

http://unicode.org/L2/L2010/10038-fcd10646-main.pdf


なぜ私が自分の質問に答えているのかを説明するために。SOの質問はすべて発射する準備ができていました。妻が私のオフィスに入ってきました。彼女は私の肩越しに見た後、私の耳元でささやきました。ただし、妻の甘いものがコミュニティの別のメンバーを助ける場合に備えて、私はまだ質問をして自分で答えました.

于 2021-04-24T15:40:25.803 に答える