ED A0 80 ED B0 80是一个有效的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
这由以下代码validation。
现在这似乎告诉我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
由于谷歌搜索使用的是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))); } } }
ED A0 80 ED B0 80
是UTF-16代理对D800 DC00
的UTF-8编码。 在UTF-8中不允许这样做:
但是,D800和DFFF之间的UCS-2值对(Unicode术语中的代理对)……需要特殊处理: 必须撤消UTF-16转换 ,产生UCS-4字符,然后如上所述进行转换。
但是,这种编码用于CESU-8和Java的“Modified UTF-8”。
由于谷歌搜索使用的是UTF-8编码方案(如果我错了,请纠正我),
基于搜索框,Google似乎正在使用某种编码自动检测function。 如果你传递F0 90 80 80
,它是有效的UTF-8,它会将其解释为UTF-8( 𐀀
)。 如果你传递ED A0 80 ED B0 80
,这是无效的UTF-8,它会将其解释为windows-1252 ( í €í°€
)。
Java的UTF8实际上是CESU-8的变种。 第一种情况是使用以UTF8“style”编码的代理对。
F0 90 80 80
解码为U+10000
,或LINEAR B SYLLABLE B008 A
ED A0 80 ED B0 80
解码为U+d800 U+dc00
。