首页 > 解决方案 > UTF-16 编码的错误字节

问题描述

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

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

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

我错过了什么 ?

标签: javaunicodeutf-16

解决方案


您错过了一些 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+D83D U+DE2D,就像byte[]它一样[-40, 61, -34, 45]


推荐阅读