ED A0 80 ED B0 80是一个有效的UTF-8字节序列吗?

时间:2012-01-12 23:12:56

标签: java language-agnostic unicode utf-8

java.nio.charset.Charset.forName("utf8").decode解码

的字节序列
 ED A0 80 ED B0 80

进入Unicode代码点:

 U+10000

java.nio.charset.Charset.forName("utf8").decode也解码

的字节序列
 F0 90 80 80

进入Unicode代码点:

 U+10000

这由code below验证。

现在这似乎告诉我UTF-8编码方案会将ED A0 80 ED B0 80F0 90 80 80解码为同一个unicode代码点。

但是,如果我访问https://www.google.com/search?query=%ED%A0%80%ED%B0%80

我可以看到它与页面https://www.google.com/search?query=%F0%90%80%80

明显不同

由于Google搜索使用的是UTF-8编码方案(如果我错了,请更正我),

这表明UTF-8不会将ED A0 80 ED B0 80F0 90 80 80解码为相同的unicode代码点。

所以基本上我想知道,按照官方标准,UTF-8应该将ED A0 80 ED B0 80字节序列解码为Unicode代码点U + 10000吗?

代码

public class Test {

    public static void main(String args[]) {
        java.nio.ByteBuffer bb = java.nio.ByteBuffer.wrap(new byte[] { (byte) 0xED, (byte) 0xA0, (byte) 0x80, (byte) 0xED, (byte) 0xB0, (byte) 0x80 });
        java.nio.CharBuffer cb = java.nio.charset.Charset.forName("utf8").decode(bb);
        for (int x = 0, xx = cb.limit(); x < xx; ++x) {
            System.out.println(Integer.toHexString(cb.get(x)));
        }
        System.out.println();
        bb = java.nio.ByteBuffer.wrap(new byte[] { (byte) 0xF0, (byte) 0x90, (byte) 0x80, (byte) 0x80 });
        cb = java.nio.charset.Charset.forName("utf8").decode(bb);
        for (int x = 0, xx = cb.limit(); x < xx; ++x) {
            System.out.println(Integer.toHexString(cb.get(x)));
        }
    }
}

3 个答案:

答案 0 :(得分:11)

ED A0 80 ED B0 80是UTF-16代理对D800 DC00的UTF-8编码。这是<{3}}

中允许的
  

但是,D800和DFFF之间的UCS-2值对(代理对   用Unicode的说法)...需要特殊处理: UTF-16   转换必须撤消,产生一个UCS-4字符   改变如上。

但是,UTF-8和Java的“修改过的UTF-8”中使用了这样的编码

  

由于Google搜索使用的是UTF-8编码方案(如果我错了,请更正我),

基于搜索框,Google似乎正在使用某种编码自动检测功能。如果您传递F0 90 80 80(有效的UTF-8),它会将其解释为UTF-8()。如果您传递了ED A0 80 ED B0 80,这是无效的UTF-8,则会将其解释为CESU-8í�€í°€)。

答案 1 :(得分:1)

Java的UTF8实际上是CESU-8变体。第一种情况是使用以UTF8“style”编码的代理对。

答案 2 :(得分:0)

F0 90 80 80

解码为U+10000LINEAR B SYLLABLE B008 A

ED A0 80 ED B0 80

解码为U+d800 U+dc00