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 80
和F0 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 80
和F0 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)));
}
}
}
答案 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+10000
或LINEAR B SYLLABLE B008 A
。
ED A0 80 ED B0 80
解码为U+d800 U+dc00
。