GBK 和 Unicode 之间的转换问题
1. GBK 被解密为 UTF-8
正常的 GBK
字节流,以为是 UTF-8
,所以用 UTF-8
去解码:
- 输出特点:一堆的黑色菱形+问号
- 输出示例:�Ҳ�����
@Test
public void test() throws UnsupportedEncodingException {
String str = "我不是锟斤拷";
byte[] buff = str.getBytes("GBK"); // 这里只要不抛异常,数据一定不会被破坏
String str1 = new String(buff, "UTF-8");
}
2. UTF-8 被解密为 GBK
正常的 UTF-8
字节流,以为是 GBK
,所以用 GBK
去解码:
- 输出示例:鎴戜笉鏄敓鏂ゆ嫹
@Test
public void test() throws UnsupportedEncodingException {
String str = "我不是锟斤拷";
byte[] buff = str.getBytes("UTF-8"); // 这里只要不抛异常,数据一定不会被破坏
String str1 = new String(buff, "GBK"); // 这里破坏了
}
3. “锟斤拷"的由来
正常的 GBK
字节流,中途被 UTF-8
解码了,又用 GBK
解码一遍:
- 输出特点:锟斤拷锟斤拷
- 输出示例:锟揭诧拷锟斤拷锟斤拷
@Test
public void test() throws UnsupportedEncodingException {
String str = "我不是锟斤拷";
byte[] gbk = str.getBytes("GBK"); // 原来的 GBK
str = new String(gbk, "UTF-8"); // 中途被转为 UTF-8
String str1 = new String(str.getBytes(StandardCharsets.UTF_8), "GBK");
}
总结分析
- 情况 1、2 是使用错误编码方式
- 情况 3 是中途被改变的(如 HTTP 请求回来,默认用
UTF8
生成字符串,此时就被转码了)
Reference
[1] pollyduan. 一段 java 代码带你认识锟斤拷[EB/OL]. https://cloud.tencent.com/developer/article/1532357 , 2019-11-04.