[概述]
在Windows操作系统中使用记事本新建一个文本文件,在文件里面写入“联通”两个字并保存。当再次打开这个文本文件时候,在记事本中看到得却不是刚刚输入的“联通”,而是乱码。网络上有人把这个奇怪现象包装成把戏,如果你曾遇到过这种把戏就会知道,他们往往让你建立两个文本文件进行对比,其中一个输入“联通”,另外一个可能是“移动”等等,最后试图八卦地让你相信联通、移动和微软之间有着种种恩怨情仇。
[解释]
这是一个字符编码应用的奇怪现象,讲的明白点,可以说是记事本开小差了!记事本为什么会犯错误?记事本犯了怎样的错误呢?也许你会迫不及待的想知道这些问题,如果是这样,我不会让你空腹而归的。
在简体中文操作系统中默认的本地字符集编码是GBK编码,除非你在保存记事本文本文件时候选择了其他编码方式,否则用记事本录入的字符信息将使用GBK编码进行储存。巧合的是,“联通”这两个字符的GBK编码具有UTF-8编码的特征,记事本犯下的错误正是将GBK编码存放的记录有“联通”两个字符的文件误认为UTF-8编码的文件。或许你会问,UTF-8编码的文件不是以“EF BB BF”三个特殊字节开头吗?既然这样,记事本怎么会犯这么低级的错误呢?没错,UTF-8编码规定使用UTF-8编码的文件以“EF BB BF”三个特殊字节开头,但并不是强制性要求,早期的UTF-8编码文件就不遵循这个规定。因此记事本不能依靠文件的开头字节判断一个文件是否是UTF-8编码,而只能对文件中的数据进行简单的编码分析来确定。正是这个原因,才有了字符编码应用中的这个奇怪又无法避免的现象。
[细节]
如果上面的解释对于你来说只是杯开胃红酒,那我还是块点把主食呈上吧,一份大峡谷香烤猪肋排。UTF-8编码采用1-3个字节对字符进行编码,编码字节数与字符的Unicode编码值有严格的对应关系,让我们回忆下UTF-8编码和Unicode的对应关系吧。
Unicode编码值 UTF-8编码结构
\u0001 - \u007E 0XXXXXXX
\u0080 - \u07FF 和 \u0000 110XXXXX 10XXXXXX
\u0800 - \uFFFF 1110XXXX 10XXXXXX 10XXXXXX
“联通”这两个字符的GBK编码值是“C1 AA CD A8",GBK编码方式使用两个字节对一个字符进行编码,因此以GBK编码方式存放的录有“联通”两个字符的文件的大小为四个字节。接下来分别观察“联通”这两个字符GBK编码值的二进制形式,你有发现有趣的事。
联 GBK 十六进制:C1 AA 二进制:1100 0001,1010 1010
通 GBK 十六进制:C1 AA 二进制:1100 1101,1010 1000
请注意上面二进制数据的着色部分,你想到了什么?对,它们和UTF-8编码结构中的补充位完全一致,UTF-8编码的补充位使得编码值更有规律,而记事本刚好凭借这个特征区分UTF-8编码的文件。存有“联通”两个字符的文件的所有数据都符合这个特征,就是这样,记事本彻底的将文件误认为UTF-8编码的文件。
将错就错,让我们来看看这个错误是怎样收场的。如果把“联通”的GBK编码值当作UTF-8编码值,那文件就成为一个写有数据“C1 AA CD A8”并以UTF-8编码的文件,当使用记事本再次打开的时候会看到什么呢?只要将UTF-8编码转换成Unicode编码就知道了。UTF-8编码“C1 AA CD A8”转换成Unicode编码后,编码值为“6A 00 68 03”(转换方法请参考本Blog中的《字符编码》一文)。0x006A这个Unicode编码值位于\u0001 - \u007E之间,若要转换为UTF-8编码,显然只能用一个字节进行编码,因此“联”的GBK编码“C1 AA”虽然特征上貌似UTF-8编码,但它却不对应任何一个UTF-8编码。接着看0x0368这个Unicode编码值,这个值对应了字符“ͨ”,这也正是我们将在记事本中看到的内容。或许你会说我看到的是一个黑色矩形啊,这只是字体的原因,你将字体改为宋体或者其他字体,看到的就是字符“ͨ”。
对于中文字符,UTF-8编码要用三个字节进行编码,因此,如果你使用记事本录入“联通”,然后选择以UTF-8编码方式保存的话,文件大小应为9个字节(包含三个字节的开头数据),而同样的文件GBK编码却是4个字节。最后附上“联通”的GBK、UTF-8、Unicode编码值,以及记事本的错误思维。
联通 GBK C1 AA CD A8 UTF-8 E8 81 94 E9 80 9A Unicode 54 80 1A 90
联通 GBK C1 AA CD A8 UTF-8 C1 AA CD A8 Unicode 6A 00 68 03 (将GBK值误认为UTF-8值的结果)
分享到:
相关推荐
在开发一个简单的Java Web应用接口,用于删除包含中文字段的数据库记录时,开发者遇到一个奇怪的现象:尽管接口没有返回错误,但实际的数据并没有被删除。开发者尝试在本地环境中使用相同的代码执行删除操作,发现...
找到正确的配置文件后,可以将其复制到一个适合的位置,如 `/etc/my.cnf`,并进行编辑。使用文本编辑器(如 `vi`)打开该文件,并添加或修改以下配置项: ```ini [mysqld] default-character-set=utf8 [client...
这种现象往往发生在解压压缩包或导入特定格式文件(如CSV)到某些应用程序时。本文旨在针对Win11和Win10系统中的此类问题提供详细的解决方案。 #### 问题概述 中文文件名乱码现象主要发生在以下几种情况: 1. **解...
当涉及到中文字符时,如果没有正确处理字符编码,就可能出现乱码现象。以下是关于解决jquery向.ashx文件post中文乱码问题的详细知识点。 首先,从环境中可以看到,开发者使用的是Visual Studio 2005,并且由于未...
python教程学习
tdac034.pdf
veclibm111111111111
nssm工具,进行2次解压后即可
视讯镜头优化,操作不走
【数据结构】的资源,包括书籍、在线课程和网站
北京大学-DeepSeek系列-提示词工程和落地场景.pdf.png
【财信国际经济研究院-2025研报】2025年2月CPI和PPI数据点评:通胀低于预期,内需亟待提振.pdf
【毕业设计】java-springboot+vue精品在线试题库系统源码(完整前后端+mysql+说明文档+LunW).zip
python安装-25.求 a 的 b 次方——有点不好意思哈.py
代码实现了自适应IMM(交互式多模型)算法,专注于对目标状态进行估计,并结合了匀速(CV)和匀加速(CA)运动模型。它使用自适应观测噪声估计和扩展卡尔曼滤波器(EKF)作为滤波主体,并在最后提供误差统计特性输出。
中产品工业物联网联网的基础功能,是企业开启数字化转型的入门之选。它能帮助企业快速搭建起基础的设备数据采集与监控体系,以较低成本实
北京大学DeepSeek系列-DeepSeek与AIGC应用.pdf.png
【毕业设计-java】springboot-vue基于多维分类的知识管理系统实现源码(完整前后端+mysql+说明文档+LunW).zip
## 一、数据介绍 本数据参考C刊《管理评论》佟岩(2024)老师的做法,使用各年度省级政府工作报告中“减碳”关键词的词频总数来测度地方政府对“减碳”的重视程度,“减碳”关键词包括二氧化碳、低碳、减排、节能、能耗、环境保护(环保)、生态、绿色。 本数据包含:原始数据、参考文献、代码do文件、最终结果。 ## 二、参考文献: 佟岩,李鑫,徐国铨.企业集团碳减排压力与债务分布-来自高耗能上市公司的经验证据[J].管理评论,2024,36(02):210-221.DOI:10.14120/j.cnki.cn11-5057/f.2024.02.014 ## 三、相关数据:城市、城市编码、年份、减碳重视程度词频。
python教程学习