其他章节:
字符集编码的发展与简介(一):ASCII码
字符集编码的发展与简介(二):ANSI
字符集编码的发展与简介(三):UNICODE
字符集编码的发展与简介(四):字符集编码模型
本节目录
ANSI发展史
随着个人计算机的发展和普及,软硬件制造商面临着走出美国、标准国际化的问题。于是便出现了一个问题:一开始的 ASCII 编码标准无法表示其他国家的语言符号。即使是在主流语言使用拉丁字母的欧洲,也存在很多拓展体,比如法语中的é,挪威语中的 Å,都无法用 ASCII 表示。 [14]
于是大家开始把 ASCII 码中最前面未使用的那一个 bit 拿来使用,原来的128种状态就变成了256种状态。这样既完美兼容了原先的ASCII,又能表达欧洲国家特定字符。
比如 IBM 为 DOS 开发了 codepage 437,采用 ASCII 并添加英式英语和一些主要欧洲语言所需的字符,以及图形字符(如用于创建用户界面元素的 DOS 应用程序的线条绘制字符)。IBM 还创建了其他 DOS 代码页,以满足使用其他语言或脚本的其他市场。例如,codepage 852用于使用拉丁字母的东欧语言,codepage 855用于俄语和其他一些使用西里尔字母的东欧语言等。当微软开始开发 Windows 时,开发了 codepage 1252用于编码西欧字符。苹果、施乐等也都制定了自己的 codepage 标准。 [13] [14]
但是这样依然存在两个问题,一是各个公司各自制定自己的扩展编码,相互之间互不兼容;二是即便是256个字符,仍然无法在一个 codepage 中表达所有的欧洲字符。
为了解决这两个问题,国际标准化组织 ISO 和 IEC 联合制定了一组标准叫 ISO/IEC 8859(简称 ISO 8859)。这里需要注意的是,ISO 8859 并不是一个具体的字符集编码标准,而是一组字符集的合称,称为ISO 8859-n,n=1,2,3,…,15,16(其中12未定义,所以共15个代码页)。其中使用最广泛的是美国国家标准协会(ANSI)起草的标准 ISO/IEC 8859-1,又称 latin 1,收录了西欧常用字符,包括德语、意大利语、葡萄牙语、西班牙语等。 [14]
上述的字符集编码标准都是 单字节编码 。而且各个字符集编码标准对多出来的128个字符的定义是不同的,即各个 codepage 之间是并不兼容的。
当计算机厂商进入东亚市场时,对于中日韩这种表意文字,256的代码空间根本就不够用。因此,中文、日文和韩文的代码页使用双字节编码,即混合使用一个或两个字节序列来表示字符。 [13]
术语解释:代码页、代码点、代码空间、ANSI
有必要再解释一下术语微软代码页(Windows codepages)和 ANSI 的由来:
微软在开发Windows时,美国国家标准协会(ANSI)正在起草一项标准,该标准最终被国际标准化组织收录并成为 ISO 8859-1 “Latin 1”。微软基于该标准创建了代码页 1252,应用于早期的 Windows,并开始将这套标准称之为“ ANSI 代码页(codepage)” [13,26] 。而且微软在后面收录其它字符集编码标准时,仍然将这些采用了以8位为编码单元的字符集称为代码页(codepage)。
也就是说,目前在Windows上下文中,术语“ANSI文本”、“代码页”或“ANSI代码页”应该被理解为使用8位编码单元的微软代码页而不是Unicode编码的文本。 [13]
这些代码页(codepage)不同的地方在于其收录的编码字符的个数和种类。在一个代码页中,每个字符在当前代码页中的整数序号,称之为代码点(codepoint),或者说的专业一点,代码点表示给定字符的编码表示形式。编码标准中代码点的有效范围称为代码空间(codespace)。[13]
(1)国标码(GB)
国标码(GB码)是中文系统的ANSI编码,作为中国公民,有必要稍微深入了解一下GB系列编码标准。参考文献 [14] 对GB码进行了比较深入的介绍,如想了解请转至该文章。
(1)GB2312
中国国家标准总局于1980年发布,7445个字符。属于变长编码,用 1~2 个字节表示字符,而字节最高位的值决定了字符占用的字节数。[14]
(2)GBK
中国国家标准总局于1995年指定,是汉语拼音GuoBiaoKuozhan(国标扩展)的首字母缩写。GBK完全兼容GB2312-1980,同时收录了Big5中全部的繁体字,以及GB2312中没有的其他汉字 [14]。共收录了21886个字符,在微软代码页中的编号为CP936 [9]。
(3)GB18030
随着字符集编码国际标准ISO/IEC 10646 和Unicode的不断发展,越来越多的字符被纳入其中,而GBK一共才2万多个字符(并且主要是汉字),有点赶不上时代了。于是中国国家标准总局于2000年又指定了新的标准GB18030-2000,用来代替GBK,后序又发布了GB18030-2005,补充了一些字符。[14]
GB18030的目标是向Unicode/UCS对齐。GB18030在GBK基础上增加了CJK(中日韩)统一汉字扩充的汉字,还包含多种我国少数民族文字(如藏、蒙古、傣、彝、朝鲜、维吾尔文等)。GB18030共有70000多个字符。[14]
GB18030包含三种长度的编码:单字节的 ASCII、双字节的 GBK(略带扩展)、以及用于填补所有Unicode 码位的四字节UTF区块。[14]
在微软代码页中的编号为CP54936。[9]
(4)Big5
Big5,是台湾使用的编码标准,编码了台湾使用的繁体汉字,大概有8千多个。[9]
(5)HKSCS
HKSCS,是中国香港使用的编码标准,字体也是繁体,但跟Big5有所不同。[9]
国标码编码形式
由上面的内容可知,中国大陆主要有三种ANSI编码:GB2312、GBK和GB18030,这三种字符集的编码形式都是一样的,只是字符集的代码空间不同。因此,接下来以GBK编码为例,介绍一下国标码的编码形式。
GBK中是用1个字节或2个字节来表示一个字符:GBK的中文编码是双字节来表示的,英文编码是用ASCII码表示的,即用单字节表示。但GBK编码表中也有英文字符的双字节表示形式,所以英文字母可以有两种GBK表示方式。为区分中文,将其最高位都定成1。英文单字节最高位都为0。当用GBK解码时,若高字节最高位为0,则用ASCII码表解码;若高字节最高位为1,则用GBK编码表解码。[27]
GB2312编码是基于区位码的,在一个双字节编码中,第一个字节表示“区号”,后一个字节表示“位号”。中文汉字的编号区号是从16开始的,位号从1开始。前面的区号有一些符号、数字、字母、注音符号(台)、制表符、日文等等。[27]
对于汉字的双字节编码来说,其编码方式位:0xA0+区号,0xA0+位号。如汉子“安”,区位号是1618(十进制),那么“安”字的GB2312编码就是 0xA0+16 0xA0+18 也就是 0xB0 0xB2 。根据区位码表,GB2312的汉字编码范围是0xB0A1~0xF7FE。[27]
双字节符号可以表达的64K空间如下图所示。绿色和黄色区域是GBK的编码,红色是用户定义区域。没有颜色区域是不正确的代码组合:[27]
MBCS (多字节字符集)
MBCS(Muilti-Bytes Charecter Set, 多字节字符集) 是一种统称,是微软引入的概念。其包含两种形式,分别是单字节字符集(SBCS)和双字节字符集(DBCS)。最常见的 MBCS 实现是双字节字符集 (DBCS)。 通常,Visual C++对 DBCS 完全启用 [18]。且在MFC中,MBCS仅支持DBCS [19]。
单字节字符集(Single-Byte Character Set, 简写为SBCS):它所有字符都只有一个字节的长度。常见字符集有:ASCII码和扩展ASCII码。SBCS字符串由一个零字节 ‘/0’ 结尾,数据类型是char。 [20] [29]
双字节字符集(Double-Byte Character Set, 简写为DBCS):这个方案是为了解决中日韩三国象形文字符号很多而诞生的,DBCS的代码空间扩展到了两个字节,也就是2^16位。其中0 ~ 127是与ASCII一致的,仅用一个字节就可以表示;但是高于127的代码点就需要用两个字节来表示了 [21] 。当宽度是两个字节时,第一个字节是前导字节,与尾随字节一起指定一个唯一的字符编码 [19] 。前导字节的范围是固定的,哪个范围的字节可以是前导字节取决于正在使用的代码页。 例如,日语代码页 932 将 0x81 到 0x9F 的范围用作前导字节,而朝鲜语代码页 949 使用不同的范围 [18] 。根据本文上一节的内容,汉字的前导字节范围为0xA0~0xFF。
因此在DBCS下,当拿到一个字符串的时候,就需要检查每个字节以确定它是否为双字节存储单元的首个字节。
在微软下,不论哪个地区,多字节字符集(MBCS)仅支持双字节字符集(DBCS)。[19]
综上所述,多字节字符集 (MBCS) 是一种支持无法用单字节表示的字符集(中日韩字符)的旧方法。 在MSDN中,建议在新的开发中,对所有文本字符串(最终用户不会看到的系统字符串也许可以除外)使用 Unicode。 MBCS 是旧技术,不建议用于新开发。[18]
全文参考文献
[1] 优快云. 你真的懂Unicode和UTF-8是什么关系吗?来看看这个就彻底懂了![DB/OL]. (2018-11-19). https://blog.youkuaiyun.com/zhusongziye/article/details/84261211
[2] 优快云. Unicode和UTF-8的关系[DB/OL]. (2022-11-23). https://blog.youkuaiyun.com/song854601134/article/details/127994299
[3] 博客园. Unicode和UTF-8的关系[DB/OL]. (2019-05-12). https://www.cnblogs.com/tsingke/p/10853936.html
[4] 知乎. Unicode和utf8的关系是什么?[DB/OL]. (2022-10-30). https://www.zhihu.com/question/274104168/answer/2737298850
[5] 成都信息工程大学. 网页编码UTF-8,GBK,GB2312的区别[DB/OL]. (2015-10-17). http://jszx.cuit.edu.cn/NewsCont.asp?type=1009&id=20573
[6] 曹晖.字符集与字符编码标准[J].西北民族大学学报(自然科学版),2006,(03):36-42.
[7] 优快云. ANSI是什么编码?[DB/OL]. (2022-06-12). https://blog.youkuaiyun.com/weixin_38293850/article/details/125248400
[8] 优快云. ANSI和UNICODE编码区别[DB/OL]. (2022-08-20). https://blog.youkuaiyun.com/u010164190/article/details/126433688
[9] 优快云. ANSI是什么编码?[DB/OL]. (2020-08-07). https://blog.youkuaiyun.com/Liuqz2009/article/details/107861408
[10] JOEL SPOLSKY. The Absolute Minimum Every Software Developer Absolutely Positively Must Know About Unicode and Character Sets[DB/OL]. (2003-10-08). The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) – Joel on Software
[11] 腾讯云开发者社区. 编码、R与Windows(一) [DB/OL]. (2020-10-23). https://cloud.tencent.com/developer/article/1727834
[12] Computers & Writing Systems. Understanding Unicode [DB/OL]. (2001-06-13). http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter04a
[13] Computers & Writing Systems. Character set encoding basics [DB/OL]. (2001-06-13). https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter03
[14] 知乎. 字符集编码(一):Unicode之前 [DB/OL]. (2023-04-24). https://zhuanlan.zhihu.com/p/468843643
[15] 知乎. UTF-8到底是什么意思?uicode编码简介 [DB/OL]. (2020-05-03). https://zhuanlan.zhihu.com/p/137875615
[16] 优快云. Unicode编码详解(四):UTF-16编码[DB/OL]. (2022-02-12). https://blog.youkuaiyun.com/hyongilfmmm/article/details/112046816
[17] 优快云. ANSI、MBCS、UNICODE字符集[DB/OL]. (2020-05-23). https://blog.youkuaiyun.com/fenghaiyang198848/article/details/106301653
[18] Microsoft文档. 支持多字节字符集 (MBCS) [DB/OL]. (2023-06-16). https://learn.microsoft.com/zh-cn/cpp/text/support-for-multibyte-character-sets-mbcss?view=msvc-170
[19] Microsoft文档. Unicode 和多字节字符集 (MBCS) 支持 [DB/OL]. (2023-04-03). https://learn.microsoft.com/zh-cn/cpp/atl-mfc-shared/unicode-and-multibyte-character-set-mbcs-support?view=msvc-170
[20] 优快云. ANSI、MBCS、UNICODE字符集 [DB/OL]. (2020-05-23). https://blog.youkuaiyun.com/fenghaiyang198848/article/details/106301653
[21] Charles Petzold. Windows程序设计(第7版)[M]. 北京: 清华大学出版社, 2000.
[22] UNICODE官网. About the Unicode Consortium [DB/OL]. https://home.unicode.org/about-unicode/
[23] UNICODE官网. Unicode标准:技术介绍 [DB/OL]. (2019.08.23). https://www.unicode.org/standard/principles.html
[24] UNICODE官网. Unicode15.0.0 [DB/OL]. (2022.09.13). https://www.unicode.org/versions/Unicode15.0.0/
[25] 优快云. Unicode了解一下:码位分布[DB/OL]. (2018.04.21). https://blog.youkuaiyun.com/oyji1992/article/details/80030366
[26] Microsoft文档. 字符集 [DB/OL]. (2023-06-16). https://learn.microsoft.com/zh-cn/windows/win32/intl/character-sets
[27] 博客园. 汉字编码之GBK编码[DB/OL]. (2020-11-05). https://www.cnblogs.com/Malphite/p/13931511.html
[28] 优快云. 汉字编码之GBK编码(附完整码表)[DB/OL]. (2016-03-04). https://learn.microsoft.com/zh-cn/windows/win32/intl/character-sets
[29] Microsoft文档. SBCS 和 MBCS 数据类型 [DB/OL]. (2023-06-16). https://learn.microsoft.com/zh-cn/cpp/c-runtime-library/sbcs-and-mbcs-data-types?view=msvc-170
[30] Microsoft文档. Unicode 和 MBCS [DB/OL]. (2023-06-16). https://learn.microsoft.com/zh-cn/cpp/text/unicode-and-mbcs?view=msvc-170