我有一个字符串可以输入我的程序。
4 个字母 A、O、“带元音变音的 E”、L
“E with an umlaut”的十六进制代码是 0xc38b。见UTF-8 encoding table and Unicode characters并查找“带分音符的拉丁文大写字母 E”
然后就变得奇怪了
我的 java 代码不是打印“E with an umlaut”而是“A with a ~”然后是 0x8b
当我将字符串转换为字节数组并将其打印为十六进制时,我的 4 个字符的字符串变成了 7 个字符:
byte[0]=41 "A"
byte[1]=4f "O"
byte[2]=c3 c383 is "A with a ~" (per above link)
byte[3]=83
byte[4]=c2 c28b is some kind of control character (per above link)
byte[5]=8b
byte[6]=4c "L"
我已经通过 Charset.defaultCharset() 验证了我的编码是 UTF-8
它几乎看起来像是错误地解释了字节,但这怎么可能呢?
谁能解释为什么这个字符串的字节解释被搞砸了,我该如何纠正它?
最佳答案
在某处,您的输入使用 UTF-8 编码,然后使用 ISO 8859-1(或类似的单字节编码)解码。此时字符串已损坏。
使用 UTF-8 对 “È”
进行编码会生成字节 [ 0xC3 0x8B ]
。使用 ISO 8859-1 对此进行解码会产生损坏的字符串 "Ë"
("\u00C3\u008B"
)。使用 UTF-8 对该字符串重新编码会生成原始问题的字节序列,[ 0xC3 0x83 0xC2 0x8B ]
确定 ISO 8859-1 在何处被错误地用于解码 UTF-8 数据,并改为指定 UTF-8。
这是解码网络请求或响应时的常见问题。除非明确覆盖,否则标准将 ISO 8859-1 指定为字符编码,因此框架默认回退到此。
关于java、utf8、国际字符和字节解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39495225/