什么是阅读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
然而,当将以下ISO 10646字符编码为UTF-16时,它似乎是4个字节,但读取前导2个字节似乎并没有表明它会这么长:
虽然我更愿意保持我的问题与软件无关;以下SQL将在Microsoft SQL Server 2019上复现此行为,默认排序规则和默认语言。(请注意,SQL Server是小端序)。
很简单,你如何/为什么读取
从阅读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排序规则),但也通过在线解码进行了验证:
字符 | Unicode名称 | ISO 10646 | UTF-16编码(十六进制,大端序) | 大小(字节) |
---|---|---|---|---|
A | LATIN CAPITAL LETTER A | U+0041 | 00 41 |
2 |
Б | CYRILLIC CAPITAL LETTER BE | U+0411 | 04 11 |
2 |
ァ | KATAKANA LETTER SMALL A | U+30A1 | 30 A1 |
2 |
RABBIT FACE | U+1F430 | D8 3D DC 30 |
4 |
字符 | Unicode名称 | UTF-16编码(十六进制,大端序) | 大小(字节) |
---|---|---|---|
⚕️ | 埃斯库勒庇斯之杖 | 26 95 FE 0F |
4 |
select cast(N'⚕️' as varbinary);
----------
0x95260FFE
很简单,你如何/为什么读取
0x2695
并认为“我需要读取下一个字来表示这个字符。”?为什么这似乎与已发布的UTF-16标准不一致?
D83D DC69 200D D83D DC69 200D D83D DC66 200D D83D DC66
、D83C DFF3 FE0F 200D D83C DF08
和D83D DC67 D83C DFFB
。 - phuclv