来自UTF-16编码的字节错误

时间:2019-03-26 09:04:45

标签: java unicode utf-16

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

1)由于二进制表示形式大于2个字节,因此我使用4个字节

XXXXXXXX XXXXXXX1 11110110 00101101

2)现在,我将所有的“ X”替换为“ 0”

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 ""

我想念什么?

1 个答案:

答案 0 :(得分:6)

您错过了一些UTF字符存储为surrogate pairs的情况:

  

在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+D83D U+DE2D表示,因为byte[]就是[-40, 61, -34, 45]