[概述]
在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值的结果)
分享到:
相关推荐
GB2312 是中国大陆规定的字符集和编码,取消了 EASCII 的扩展字符,规定一个小于 127 的字符的意义与原来相同,但两个大于 127 的字符连在一起时,就表示一个汉字。GB2312 编码使用两个字节表示一个汉字,前面的一个...
Java字符编码监听器是Java Web开发中的一个重要概念,主要用于处理HTTP请求和响应中的字符编码问题。在Java Servlet规范中,提供了`SetCharacterEncodingFilter`这样的过滤器,用于确保请求参数和响应内容的正确编码...
Unicode是一种国际化的字符编码标准,旨在为每种语言的每一个字符提供唯一的编码,从而避免不同编码标准之间的冲突。Unicode有两种主要的编码方式:UCS-2(Unicode-16)和UCS-4(Unicode-32)。UCS-2使用两个字节来...
Unicode是一个广泛采用的字符编码标准,它旨在包含世界上所有语言的字符,包括汉字。Unicode使用固定长度的编码,通常为16位或32位,这使得不同语言的文本可以统一处理。 Unicode的实现方式有多种,其中最常见的是...
总结来说,"字符编码查询工具"是一个实用的应用,对于需要处理不同字符编码的IT专业人士来说,它是一个强大的辅助工具,能帮助他们快速了解和转换各种字符编码,从而解决可能出现的编码相关问题。通过这个工具,用户...
下面是一个具体的示例代码,展示了如何在Struts2应用中配置一个名为`encodingfilter`的过滤器,并指定其作用于所有请求路径(`/*`)上。 ```xml <filter-name>encodingfilter <filter-class>org.apache.struts2....
字符编码是计算机科学领域中一个基础且重要的概念,它涉及到信息的存储、传输和处理。字符编码定义了如何将文字、符号等字符转换成二进制形式,以便计算机理解和处理。本文将深入探讨字符与编码的概念、发展历史、...
UTF-8是Unicode字符集的一个变种,是一种变长的字符编码方式。它使用1至4个字节来表示Unicode中的每个字符,其中英文字符只需要1个字节,而大部分汉字则需要3个字节。UTF-8具有良好的向前兼容性,广泛应用于网络...
接下来,我们要讨论的是Unicode编码,这是一个更广泛的字符集,旨在容纳世界上几乎所有的文字系统。Unicode包含了ASCII,并且扩展到了超过10万的编码位置,覆盖了全球大部分语言的字符。在Unicode中,中文字符通常...
字符编码是计算机科学中的一个重要概念,它涉及到如何在数字系统中表示和处理文本。在我们的日常生活中,无论是浏览网页、编辑文档还是发送电子邮件,字符编码都在背后默默地工作,确保我们看到的文字能正确显示。...
例如,在打开一个文本文件时,如果文件的字符编码与操作系统的设置不符,将会出现乱码。使用字符编码转化可以解决这个问题。 8. 结论 使用 VC++编程可以实现文本文件的字符编码转化,从而解决字符编码不兼容的问题...
ISO 字符编码 word 格示是一种强大且灵活的字符编码方式,它可以用来表示所有 Unicode 字符,从而满足各种应用场景的需求。 在 HTML 中,ISO 字符编码 word 格示可以用来实现以下几种功能: 1. 表示特殊字符,例如...
随着信息技术的发展,全球化的趋势要求计算机能够处理不同语言的文字信息,这就需要一个统一且兼容性强的字符编码方案。 #### 二、常见字符编码类型 1. **ASCII编码** - **简介**:ASCII(American Standard Code...
字符编码查看器是一款非常实用优秀的编程软件。这款软件支持编码之间的相互转换,可以帮助用户快速查看编码等。功能非常强大。需要的朋友可以前来本站下载。...可以查看字符串的ANSI和utf-8的编码的一个小软件。 字符
此时,一个字符解码工具可以帮助你正确识别文件的原始编码并将其转换为你系统支持的编码,确保内容的正确显示。 在编程中,处理字符编码和解码的函数和库广泛存在。例如,在Python中,你可以使用`codecs`模块进行...
韩文字符编码总表
字符集编码是计算机科学中的一个重要概念,涉及到数据的存储、传输和显示。在这个"字符集编码查询/反查工具"中,我们可以看到涉及到的关键技术包括字符集、二进制、十六进制、Base64以及URL编码。这些知识点在信息...
这里的 `new String(bytes, "UTF-8")` 表示创建一个新的字符串,该字符串的字符由指定的字节数组按照 UTF-8 编码转换而来。 #### 四、具体案例分析 根据题目描述中提到的内容,我们可以看到一些具体的场景应用: ...
标题“工具-字符编码转换”指的是一个用于处理字符编码转换的软件工具,它可能帮助用户在不同的字符编码之间进行转换,以解决不同系统或程序之间的兼容性问题。字符编码是计算机存储和显示文本的一种方式,常见的有...
计算机基础课件:西文字符的编码是一个复杂的编码系统,包括西文字符集、ASCII 码、扩充 ASCII 字符集、汉字编码、国标交换码、机内码等多个方面。只有深入了解这些概念和技术,才能更好地理解和应用计算机基础知识...