A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

GBK中的数据编码后有可能和UTF-8相同导致被UTF-8解码。比如“联通”。能不能讲更具体点呢?深入点。

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1

查看全部评分

4 个回复

倒序浏览
“联通”两个字的Unicode标准编码UTF-16 (big endian)为:DE 8F 1A 90

而其UTF-8编码为:E8 BF 9E E9 80 9A

最后,当一个软件打开一个文本时,它要做的第一件事是决定这个文本究竟是使用哪种字符集的哪种编码保存的。软件有三种途径来决定文本的字符集和编码:

最标准的途径是检测文本最开头的几个字节,如下表:




回复 使用道具 举报
本帖最后由 王少岩 于 2012-8-21 18:00 编辑

在简体中文操作系统中默认的本地字符集编码是GBK编码,除非在保存记事本文本文件时候选择了其他编码方式,否则用记事本录入的字符信息将使用GBK编码进行储存。“联通”的GBK编码具有UTF-8编码的特征,记事本将GBK编码的“联通”两个字符的文件误认为UTF-8编码的文件,用UTF-8解码出现错误。
联 GBK 十六进制:C1 AA 二进制:1100 0001,1010 1010
通 GBK 十六进制:CD A8 二进制:1100 1101,1010 1000
UTF-8编码采用1-3个字节对字符进行编码,编码字节数与字符的Unicode编码值有严格的对应关系
Unicode编码值   UTF-8编码结构
u0001 - u007E  0XXXXXXX:以0开头,占一个字节
u0080 - u07FF  110XXXXX 10XXXXXX:以110开头占两个字节
u0800 - uFFFF  1110XXXX 10XXXXXX 10XXXXXX :以1110开头占三个字节
记事本凭借这个特征区分UTF-8编码的文件。“联通”两个字符的GBK编码符合这个特征,就是这样,记事本将文件误认为UTF-8编码的文件,以UTF-8进行解码出现乱码。

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

回复 使用道具 举报
首先 得到“联通”字符的GBK编码二进制形式
String str=new String("联通");
  byte[] b=str.getBytes();
  String GBKStr=new String(b,"GBK");      
  byte[] c=GBKStr.getBytes();
  for (int i = 0; i < c.length; i++)
  {
    System.out.println(Integer.toBinaryString(c&255));
   
  }
实验结果是:
11000001
10101010
11001101
10101000
参照UTF-8编码规则,你通过GBK保存的“联通”,当你再次通过记事本打开的时候,他会判断你是文件的编码格式,由于中文Windows默认的编码是GBK,所以一般只要判定UTF-8编码格式。


11000001
10101010
11001101
10101000  
上面红体字表示的二进制排列规则恰好满足,UTF-8的单字符2字节表示的规则。所以系统判定“联通”文件是UTF-8文件
应该采用UTF-8解码,但是码表里对应码字在字符表里是未知字符,所以会再次打开“联通文件”是乱码


UFT字节编码规则.png (9.06 KB, 下载次数: 33)

UTF-8编码规则

UTF-8编码规则

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

回复 使用道具 举报
问题已经解决
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马