网页乱码引发的思考

2015-09-10 07:22张北一
中国信息技术教育 2015年23期
关键词:二进制记事本字符

张北一

网页设计与制作是北京市现行信息技术教材信息技术基础中的重要内容。教师在备课时通过研读教材可以发现,网页是加工和表达信息的一种强大载体,基本网页制作技术也是高中生应会的基本技能。

教材第四单元第三节指出,网页是使用HTML语言编写的纯文本文件。浏览器根据文件中所写的标签来进行显示并赋予不同文本不同的样式。所以理论上,所有文本编辑软件皆可用来编写网页。例如,Windows记事本、Sublime Text、GNU Nano都可以胜任网页编辑工作。在教学实践中,常有学生使用Windows系统自带的记事本软件编写和修改.html文件,此时就可能会有学生遇到“记事本”编写的中文页面在浏览器中乱码的问题,具体情况我们可以用一组实验来说明。

实验过程

我们使用微软Windows7 64位简体中文操作系统和internet explorer 11进行测试。测试步骤如下。

1.打开记事本软件,输入.html文档中必要的html、head、body标签。并在body标签下输入文本“This is a test.这是一个测试”。写法上页如上页图1所示。

2.将文件按默认配置保存为index.html。

3.打开internet explorer,将index.html拖拽到浏览器窗口中。发现英文字符显示正常,但中文显示为乱码(如图2)。

4.查阅网上资料后,可得知通过调节浏览器“编码”选项可以解决这一问题。我们在浏览器窗口内点击鼠标右键,在“编码”一项中勾选“自动选择”(如图3)。此后发现中文字符显示正常。

5.取消自动选择选项,尝试手动选择编码方式为“简体中文(GB2312)”或“Unicode(UTF-8)”。发现选择“简体中文(GB2312)”时中文字符正常显示;选择“Unicode(UTF-8)”时中文字符乱码。

6.确定了中文显示问题是由编码方式引起的,那么回到记事本软件并打开index.html,重新检查保存文件时的选项,发现也有“编码”一项。其默认值为“ANSI”。我们将其调节为浏览器编码选项中出现过的“UTF-8”并重新使用浏览器打开index.html后发现中文字符正常显示。

7.保持index.html的编码方式为UTF-8不变,使用浏览器打开并设置浏览器编码方式为“简体中文(GB2312)”,发现中文显示乱码。

8.继续对其他语种文字进行验证。我们先加上一行日语(如图4)。分别以ANSI、Unicode、UTF-8来保存文件,并使用浏览器以GB2312、Unicode和日语(EUC)来浏览这个文件。结果如表1所示。

9.再增加一行法语字符,这里面特别注意要包含法语中特有的字母“”,重复第八步的实验。从中我们发现保存为ANSI编码文件的时候系统提示无法保存该文件(如下页图5)。所以只存为Unicode和UTF-8两种格式。结果如下页表2。

由上面的实验我们可以得知,当保存文件所选的编码和浏览器设置的编码器一致时,各种字符皆显示正常。不一致时,部分字符会出现乱码。为了避免用户频繁切换编码方式,浏览器开发者均设置了“自动选择”选项来帮助用户自动切换编码方式。但实验中还引发了三个问题:①为什么保存文件和浏览文件时必须选择一致的编码方式才能保证文件的正常显示?②实验证实ANSI和GB2312应属同一种编码方式,但为何名称不同?二者又有什么关系?③在浏览器设置中Unicode被写作“Unicode(UTF-8)”,但记事本软件的保存选项却将“Unicode”和“UTF-8”列为不同的选项,这两者又是什么关系?

下面我们就来针对这三个问题逐一讨论。

文字在计算机内的表达

我们知道计算机内部存储信息是靠“0”和“1”这两个二进制数实现的。如果想表达其他的文字和符号,就要想一个办法用“0”和“1”来进行指代。最早的ASCII码就是使用八位(1字节)二进制数来指代数字、小写英语字母、大写英语字母和常用符号的规则。其中首位统一规定为0,此后的7位来表示不同的符号。表3为a、b、c三个小写英文字母与其二进制编码的对应关系。

这种把字符转换为二进制数在计算机内存储的做法即为“编码”。ASCII仅能满足英语语言中文字的表达,应用范围十分有限。为了方便世界各国文字和符号都能利用计算机进行存储和传输,国际标准化组织和各国的标准化结构都编制了各种文字编码方式,我们在实验中看到的GB2312、Unicode都是常用的编码方式。每种编码方式都自成一体地规定了文字和二进制数之间的对应关系。多数情况下,不同编码方式的“文字—二进制数”对应关系是不同的。我们在记事本软件中保存文件就是把文字转换为二进制数的过程,用浏览器浏览文件就是把二进制数翻译为文字的过程。如果这两个过程的标准不一致,必然会出现千奇百怪的混乱符号,也就是乱码。例如,GB2312中的汉字“中”十六进制编码为“D6D0”,转换为二进制为“11010110 11010000”。如果用另一种编码方式Unicode来翻译这组二进制数,则对应字符“”,明显和原文不符。这里要注意的是,目前多数编码方式对英语字母的二进制表达都是一致的,所以在实验第八步中英语字母总能正常显示。

汉字编码在编程中应用十分广泛。例如,Arduino单片机支持一种朗读中文的语音合成模块。在源代码中会以十六进制数组成的数组来确定发音内容。使用说明中会写清模块支持的编码方式,以便开发者查阅汉字和其十六进制数的对应关系。如果代码中写道uint8_t text[]={0xB3,0xC9},其中B3C9在gb2312中就是“成”字。模块在工作时就会发出“成”字的读音。除了语音模块,在对液晶显示模块时也需要依靠十六进制数来指代汉字。

文字编码在网络传输中同样普遍存在。我们在浏览中文维基百科时,浏览器地址栏中会显示形如“https://zh.wikipedia.org/wiki/中國”的地址,而将网址复制到文本编辑器中就会发现其中的“中國”变成了“%E4%B8%AD%E5%9C%8B”。这就是因为在传输的时候“中國”被使用UTF-8编码成了十六进制数添加到网址中,而浏览器在收到网址后又将其解码成了汉字并在地址栏显示出来。

ANSI与GB2312编码

理解了“编码”的含义后,我们就明白了记事本软件和浏览器中“编码”选项的作用了。那么记事本软件中默认的“ANSI”又是一种什么编码方式呢?实际上ANSI在不同语言的操作系统上指代的编码方式是不一样的。当我们选择编码为“ANSI”时,系统会从一种被称为“Code Page”(代码页)的编码标准中集中选取与当前操作系统语言和区域设置相符的编码标准。在微软MSDN网站的Code Page Identifiers文档中明确记载简体中文操作系统应选的Code Page标识符为“936”,名称为“gb2312”,附加信息中解释为“ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312)”。说明系统为中国和新加坡的中文用户选择GB2312为指定编码方式。而GB2312是中国国家标准总局所颁布的《信息交换用汉字字符集》,也就是我国所统一规定的汉字编码依据。其中规定了包含英语字母、中文汉字、日语假名、希腊字母等7445个符号。这就是为什么选择以ANSI保存文件后应该将浏览器“编码”选项设置为“简体中文(GB2312)”才能正常阅读汉字和日文的原因。

ANSI Code Page是Windows操作系统独有的编码方式集合,其包含了很多种适用于各国语言的编码方式。在Windows中,用户也可以自己决定系统选择何种编码方式来解码应用程序中的文字符号。我们可以在“控制面板→区域→管理→更改系统区域设置”这一选项中选择。中国大陆一般会选择为“中文(简体,中国)”。如果经常运行繁体中文软件,则可以选择为“中文(繁体,香港特别行政区)”等。

有一些Windows软件可能不会在编码方式选项中直接提供“ANSI”选项,但会提供含有Code Page标识符的选项,让用户不受系统自动选择编码方式的限制。在我们常用的SSH工具“Putty”中,其“Translation”选项中就提供了形如“Win 1250”“Win 1256”等选项。其中“1250”“1256”就是Code Page标识符,分别代表了中欧和阿拉伯。

Unicode编码

GB2312虽然能解决大部分的我国常用文字符号的编码问题,但其中仍然没有包含法语等其他国家的字符。那么有没有一种编码方式能解决各国所有文字的编码问题呢?答案是肯定的,那就是实验第九步中系统向我们提示的“Unicode”。Unicode是由Unicode协会定制、发布的一种针对各国文字、符号进行编码的编码方式。所以Unicode又被称为“万国码”。Unicode诞生时规定用16位二进制数来表示一个文字或符号。但最早的Unicode和ASCII有一定差异,导致原本处理ASCII的程序没法直接处理Unicode编码的文字。于是Unicode协会又制定了一种Unicode的变种编码方式,称为UTF-8。UTF-8中,理论上最多能用48位二进制数(6字节)来表示一个文字或符号。对于单字节符号,UTF-8与ASCII一致,使得原本处理ASCII的软件几乎不用做专门的修改就能处理UTF-8与ASCII的交集中的文字和符号。表示ASCII以外的文字时,则在前8位中加入说明本字符共需要多少位的信息。我们在记事本软件中看到的“Unicode”选项的含义是每个字符占用16位的标准Unicode编码方式;“UTF-8”专指Unicode的变种UTF-8。当我们选择浏览器选项中的“Unicode(UTF-8)”时,浏览器会自动判断使用标准Unicode或者UTF-8。

在使用计算机处理非ASCII符号时要谨慎选择其编码方式。通用性良好的编码方式能使用户所编码的信息在各种环境下都能被轻松解码。例如,信息技术基础第三单元第二节中介绍了使用数据库存储信息。我们在MySQL等数据库管理系统中建立数据库时,编码方式就是一个重要的选项。选择UTF-8等包含字符量大、通用性强的编码方式会有助于各种应用程序(如PHP脚本程序)被顺利读取和解码数据库中的文字信息。也有利于正确地存储用户所提交的小语种文字、生僻字等文字符号。

以上就是对计算机文字编码的简要介绍。文字编码是信息技术中的基础知识。本文介绍的文字对十六进制数或二进制数代码转换标准是公开的。如果使用一种不公开的转换标准,就可以实现对文字的加密,由此则可以延伸讨论更多的话题。

猜你喜欢
二进制记事本字符
Python实现图片转字符画
有用的二进制
用Scratch把十进制转为二进制
正则表达式快速入门
有趣的进度
图片轻松变身ASCⅡ艺术画
小小记事本
土拨鼠的记事本
记事本里的信息技术课
视频监视系统中字符叠加技术的应用