【问题标题】:Wrong bytes from UTF-16 encodingUTF-16 编码的错误字节
【发布时间】:2019-08-16 14:35:05
【问题描述】:

我有一个角色'????' 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 ""

我错过了什么?

【问题讨论】:

标签: java unicode utf-16


【解决方案1】:

你错过了一些 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]

【讨论】:

    猜你喜欢
    • 2012-03-13
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 2012-04-01
    • 2014-01-18
    • 2011-08-18
    • 2020-06-20
    • 2020-07-17
    相关资源
    最近更新 更多