UTF-16编码中的错误字节

5

我有一个字符,它的 Unicode 值为U+1F62D,二进制等效值为11111011000101101。现在我想将此字符转换为字节数组。我的步骤是:

1) 由于二进制表示大于2字节,我使用4字节

XXXXXXXX XXXXXXX1 11110110 00101101

2)现在我用 '0' 替换所有的 'X'

00000000 00000001 11110110 00101101

3) 十进制等效值

00000000(0) 00000001(1) 11110110(-10) 00101101(45)

这是我的代码

@Test
    public void testUtf16With4Bytes() throws Exception {
        assertThat(
                new String(
                        new byte[]{0,1,-10,45},
                        StandardCharsets.UTF_16BE
                ),
                is("")
        );
    }

这是输出结果

ava.lang.AssertionError: 
Expected: is ""
     but: was ""

我错过了什么?

第一个字节是错误的。它不应该是0x0,而应该是0xD8。https://en.wikipedia.org/wiki/UTF-16#Examples - jhamon
1个回答

6

您可能会错过一些UTF字符,它们被存储为代理对

在UTF-16中,范围在U+0000—U+D7FF和U+E000—U+FFFD之间的字符被存储为单个16位单位。非BMP字符(范围在U+10000—U+10FFFF之间)被存储为“代理对”,即两个16位单位:高代理项(范围在U+D800—U+DBFF之间)后跟低代理项(范围在U+DC00—U+DFFF之间)。孤立的代理项字符在UTF-16中是无效的,代理项字符总是成对写入(高位在前,低位在后)。

字符是U+1F62D,因此它属于U+10000—U+10FFFF范围。它用代理对U+D83DU+DE2D表示,作为byte[],它将是[-40, 61, -34, 45]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接