本文主要是介绍字符编码二(各类编码方式的发展、半角和全角),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
参考链接
为了兼容ASCII码,各种编码方式在考虑多字节的字符(比如汉字)与原先的ASCII字符混用时,编码有两种方案:
方案一:保持ASCII字符为单个字节编码不变(即完全直接兼容ASCII),但将其他多字节字符编码的各个字节的最高位(即首位)设置为1,以区分于字节最高位为0的ASCII编码。使用该方案的编码方式有EASCII、ISO/IEC 8859、GB、UTF-8等。
方案二:将原先的ASCII字符重新编码为多个字节表示(即间接兼容ASCII),以便与其他多字节字符统一起来。使用该方案的编码方式有UTF-16、UTF-32等。
方案一和方案二就是在追求空间和时间上的取舍不同。
1.第一阶段:单一ASCII编码方案阶段
ASCII码(American Standard Code for Information Interchange,美国信息交换标准码),由美国国家标准学会ANSI(American National Standard Institute)于1968年正式制定。之后,ASCII编码标准又于1972年被ISO/IEC采用,制定为ISO/IEC 646标准(ISO,即国际标准化组织International Standardization Organization,成立于1946年;IEC,即国际电工技术委员会International Electrotechnical Commission,成立于1906年;ISO/IEC往往用来表示由这两大国际组织联合制定的标准)。因此,ISO/IEC 646(常简称为ISO 646)与ASCII,实际上指的是同一个编码标准。ASCII编码方案虽然不是最早出现的字符编码方案,但目前却是最基础、最重要、应用最广泛的字符编码方案。
目前所通行的其他字符编码方案,比如ISO-8859系列、GB系列(GB2312、GBK、GB18030、GB13000)、Big5、Unicode等等,均直接或间接兼容ASCII码。(注意:间接兼容实际上是不兼容,比如本身ASCII码一个字节的编码在有些编码方案或方式用两个字节表示,虽然编码值相同,实际为不兼容)
2.第二阶段:各个多家和地区各自为政的多个ANSI编码方案阶段计算机出现之后,首先逐渐从美国发展到了欧洲。
由于欧洲很多国家所用到的字符中,除了基本的、美国也用的那128个ASCII字符之外,还有很多衍生的拉丁字母等字符。比如,在法语中,字母上方有注音符号;而欧洲其他国家也有各自特有的字符。
考虑到一个字节能够表示的编码实际上有256个(2^8 = 256),而ASCII字符却只用到了一个字节中的低7位(因此在ASCII码中最高位总是为0),编号为0x00-0x7F(十进制为0~127)。
也就是说,ASCII只使用了一个字节所能表示的256个编码中的前128个(2^7 = 128)编码,而后128个编码相当于被闲置了。因此,欧洲各国纷纷打起了后面这128个编码的主意。问题在于,欧洲各国同时都有这样的想法。于是各国针对后面的0x80-0xFF(十进制为128~255)这128个编码分别对应什么样的字符,就有了各自不同的设计。于是,字符编码的历史,从第一阶段的单一ASCII编码方案阶段,发展到了各个多家和地区各自为政的多个ANSI编码方案阶段的第二阶段。
为了结束欧洲各国这种自行其是的混乱局面,于是又先后设计了两套统一的,既兼容ASCII码,又支持欧洲各国所使用的那些衍生字符的单字节编码方案:一个是EASCII(Extended ASCII)字符编码方案,另一个是ISO/IEC 8859字符编码方案。
2.1 EASCII码
EASCII码虽然与ASCII码一样使用单字节编码,但却可以表示最多256个字符(2^8 = 256),比ASCII的128个字符(2^7=128)多了一倍。因此,在EASCII码中,当第一个比特位(即字节的最高位)为0时,仍表示之前那些常用的ASCII字符(实际的二进制编码为0000 0000 ~ 0111 1111,对应的十进制就是0~127),而为1时就表示补充扩展的其他衍生字符(实际的二进制编码为1000 0000 ~ 1111 1111,对应的十进制就是128~255)。这样就在ASCII码的基础上,既保证了对ASCII码的兼容性,又补充扩展了新的字符,于是就称之为Extended ASCII码(即扩展ASCII码),简称为EASCII码。不过**,EASCII码目前已经很少使用,相当于是被废弃了**,原因在于其容纳的字符太少,而且国际化和标准化程度不够,不同厂商和平台在实现上有差异。因此,EASCII码目前已基本被容纳字符更多、设计更为优良、更具有国际化和标准化特点的ISO/IEC 8859字符编码方案取代了。
2.2 ISO/IEC 8859码
ISO/IEC 8859字符编码方案与EASCII字符编码方案类似,也同样是在ASCII码的基础上,利用了ASCII的7位编码所没有用到的最高位(首位),将编码范围从原先ASCII码的0x00-0x7F(十进制为0-127),扩展到了0x80-0xFF(十进制为128~255)。
与ASCII、EASCII字符编码方案只包括单个独立的字符集不同,ISO/IEC 8859字符编码方案包括了一组字符集,或者说ISO/IEC 8859相当于是一组字符集的总称,其内共包含了15个字符集,即ISO/IEC 8859-n,n=1、2、3…15、16,其中12未定义,所以实际上共15个。这15个字符集,大致上包括了欧洲各国所使用到的字符(甚至还包括一些外来语字符),而且每一个字符集的补充扩展部分(即除了兼容ASCII字符之外的部分),都只实际使用了0xA0-0xFF(十进制为160-255)这96个编码,而0x80-0x9F(十进制为128~159)这32个编码并未实际定义字符。
其中,目前使用得最为普遍的是ISO/IEC 8859-1字符集,收录了西欧常用字符(包括德法两国的字母)。ISO/IEC 8859-1往往简称为ISO 8859-1,而且还有一个称之为Latin-1(也写作Latin1)的别名,即:ISO/IEC 8859-1 等于ISO 8859-1 等于 Latin-1 等于 Latin1。
从ISO 8859-1到ISO 8859-16各自所收录的字符分别如下:
ISO 8859-1字符集,也称为Latin-1字符集,收录了西欧常用字符(包括德法两国的字母);
ISO 8859-2字符集,也称为Latin-2字符集,收录了东欧字符;
ISO 8859-3字符集,也称为Latin-3字符集,收录了南欧字符;
ISO 8859-4字符集,也称为Latin-4字符集,收录了北欧字符;
ISO 8859-5字符集,也称为Cyrillic字符集,收录了西里尔(斯拉夫语)字符;
ISO 8859-6字符集,也称为Arabic字符集,收录了阿拉伯语字符;
ISO 8859-7字符集,也称为Greek字符集,收录了希腊字符;
ISO 8859-8字符集,也称为Hebrew字符集,收录了希伯来语字符;
ISO 8859-9字符集,也称为Latin-5或Turkish字符集,收录了土耳其字符;
ISO 8859-10字符集,也称为Latin-6或Nordic字符集,收录了北欧(主要指斯堪地那维亚半岛)字符;
ISO 8859-11字符集,也称为Thai字符集,几乎与泰国国家标准TIS-620(1990)字符集等同, 唯一的区别是,ISO 8859-11定义了不间断空格NBSP(non-breaking space)字符(码点值为0xA0),而TIS-620中则未定义该字符;
ISO 8859-12字符集,目前尚未定义(未定义的原因目前有两种说法:一是原本要设计成一个包含凯尔特语字符的“Latin-7字符集”,但后来凯尔特语变成了ISO 8859-14 / Latin-8字符集;二是原本预留给印度天城体梵文的,但后来被搁置了);
ISO 8859-13字符集,也称为Latin-7字符集,主要函盖波罗的海(Baltic)诸国的文字符号,也补充了一些被Latin-6字符集遗漏的拉脱维亚(Latvian)字符;
ISO 8859-14字符集,也称为Latin-8字符集,它将Latin-1字符集中的某些符号换成凯尔特语(Celtic)字符;
ISO 8859-15字符集,也称为Latin-9字符集,或者被戏称为Latin-0字符集,它将Latin-1字符集中较少用到的符号删除,换成当初遗漏的法文和芬兰字母,还把英镑和日元之间的金钱符号,换成了欧盟货币符号;
ISO 8859-16字符集,也称为Latin-10字符集,涵盖了阿尔巴尼亚语、克罗地亚语、匈牙利语、意大利语、波兰语、罗马尼亚语及斯洛文尼亚语等东南欧国家语言。
2.3 简体汉字编码方案(GB2312、GBK等)
中文中的汉字就多达10多万个,一个字节只能表示256个字符,肯定是不够的,因此只能使用多个字节来表示一个字符。于是当计算机被引入到中国后,相关部门设计了GB系列编码(“GB”为“国标”的汉语拼音首字母缩写,即“国家标准”之意)。按照GB系列编码方案,在一段文本中,如果一个字节是0~127,那么这个字节的含义与ASCII编码相同,否则,这个字节和下一个字节共同组成汉字(或是GB编码定义的其他字符)。因此,GB系列编码方案向下完全直接兼容ASCII编码方案。也就是说,如果一段用GB编码方案编码的文本里的所有字符都在ASCII编码方案中有定义(即该文本全部由ASCII字符组成),那么这段GB编码实际上和ASCII编码完全一样。
2.3.1 GB2312
最早的GB编码方案是GB2312,收录的汉字不足一万个,基本能满足日常使用需求,但不包含一些生僻字,因此后来又在GB2312基础上进行了扩展。是由中国国家标准总局于1980年发布、1981年5月1日开始实施的一套国家标准,标准号为GB2312-1980。GB2312编码适用于汉字处理、汉字通信等系统之间的信息交换,通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持GB2312。GB2312编码为了避免与ASCII字符编码(0~127)相冲突,规定表示一个汉字的编码(即汉字内码)的字节其值必须大于127(即字节的最高位为1),并且必须是两个大于127的字节连在一起来共同表示一个汉字(GB2312处理ASCII码外的字符为双字节编码)。
GB2312标准共收录6763个汉字,其中一级汉字3755个,二级汉字3008个;同时,除了汉字,GB2312还收录了包括拉丁字母、希腊字母、日文平假名及片假名字符、俄语西里尔字母在内的682个字符。
可能是出于显示上视觉美观的考虑,除汉字之外的682个字符中,GB2312甚至还包括了ASCII里本来就有的数字、标点、字母等字符。也就是说,这些ASCII里原来就有的单字节编码的字符,又再编了两个字节长的GB2312编码版本。
这682个双字节编码字符就是常说的“全角”字符,而这些字符所对应的单字节编码的ASCII字符就被称之为“半角”字符。
2.3.2 GBK
微软在GB2312的基础上扩展制订了GBK(Guo-Biao Kuozhan),然后GBK才成为“国家标准”(也有说GBK不是国家标准,只是“技术规范指导性文件”);但网上也有资料说是先有GBK(由全国信息技术标准化技术委员会1995年12月1日制订),然后微软才在其内部所用的CP936代码页中以GBK为基础进行了扩展,亦即Windows系统中的CP936代码页实际上是GBK编码方案的一个实现(本人更倾向于这后一种说法。
在GB2312基础上扩展的编码方案称之为GBK(K为“扩展”的拼音首字母)。GB2312-1980共收录6763个汉字,覆盖了中国大陆99.75%的使用频率,基本满足了汉字的计算机处理需要。但对于人名、古汉语等方面出现的罕用字、生僻字,GB2312不能处理,如部分在GB2312-1980推出以后才简化的汉字(如“啰”)、部分人名用字(如歌手陶喆的“喆”字)、台湾及香港使用的繁体字、日语及朝鲜语汉字等,并未收录在内。于是全国信息技术标准化技术委员会利用GB2312-1980未使用的码点空间,收录GB13000.1-1993的全部字符,于1995年12月1日发布了《汉字内码扩展规范(GBK)》(Guo-Biao Kuozhan国家标准扩展码,是根据GB13000.1-1993(GB13000下文有详细介绍),对GB2312-1980的扩展;英文全称Chinese Internal Code Specification)。虽然GBK跟GB2312一样是双字节编码,但GBK只要求第一个字节即高字节大于127就固定表示这是一个汉字的开始(即GBK编码高字节的首位必须是1;0~127当然表示的还是ASCII字符),不再像GB2312一样要求第二个字节即低字节也必须大于127(即GBK编码低字节首位既可以是0,也可以是1)。正因为如此,作为同样是双字节编码的GBK才可以收录比GB2312更多的字符。GBK字符集向后完全兼容GB2312,同时还支持GB2312-1980不支持的部分中文简体、中文繁体、日文(不过该字符集不支持韩国文字,也是其在实际使用中与Unicode字符集相比欠缺的部分),共收录汉字21003个、符号883个,并提供1894个造字码位,简、繁体字融于一体。
微软早在Windows 95简体中文版中就采用了GBK编码,也就是对微软内部之前的代码页936(即Code Page 936,简写为CP936)进行了扩展,之前CP936和GB2312-1980几乎一模一样。(代码页后文有详细介绍)
微软的CP936通常被视为等同于GBK,连IANA(Internet Assigned Numbers Authority互联网号码分配局)也将“CP936”视作“GBK”的别名。但事实上比较起来,GBK定义的字符较CP936多出了95个(15个非汉字及80个汉字),都是当时没有收入ISO/IEC 10646 (即UCS) / Unicode的字符。
2.3.3 GB18030
又在GBK的基础上进一步扩展,称之为GB18030,加入了一些国内少数民族的文字,一些生僻字被编到了4个字节。GB18030-2000是GBK的升级版本,它的主要特点是在GBK基础上增加了CJK中日韩统一表意文字扩充A的汉字;而GB18030-2005的主要特点是在GB18030-2000基础上又增加了CJK中日韩统一表意文字扩充B的汉字。
微软也为GB18030定义了专门的代码页:CP54936,但是这个代码页实际上并没有真正使用。
包括GB2312、GBK、GB18030在内的GB系列编码方案(不包括GB13000,下同,不再赘述;GB13000编码方案下文有详解介绍),每扩展一次都完全保留之前版本的编码,所以每个新版本都向下兼容。使用GB类编码方案时一般都要时刻记住:一个汉字由两个字节组成(即一个汉字占用的存储空间相当于两个英文字符所占用的存储空间)
2.3.4 GB13000
除了逐步扩展并保持向下兼容的GB2312、GBK、GB18030等GB系列编码方案,还有一个与GB2312、GBK、GB18030等GB系列编码方案不兼容的、特殊的GB编码方案——GB13000编码方案,GB2312、GBK、GB18030的编码方式与GB13000是完全不同的。因此,习惯上所称的GB系列编码方案一般并不包括GB13000在内。GB13000是国家为了进行兼容Unicode标准,这个标准也不需要了解。
各汉字(中文字符)编码方案之间的关系(Big5为繁体汉字编码方案,主要通行于港澳台地区,本文不作详细介绍):
总结:GB类字符集均属于双字节字符集,严格来讲,广义上的“GB类字符集”包括了单字节编码的ASCII字符以及双字节编码的非ASCII字符,严格说GB类字符集属于单字节与双字节混合字符集。
基于DBCS的编码方案里,最大的特点是两字节长的中文字符和一字节长的英文字符(ASCII字符)完全兼容。
ANSI编码
在全世界所有国家和地区的文字符号统一编码的UCS/Unicode编码方案问世之前,各个国家、地区为了用计算机记录并显示自己的字符,都在ASCII编码方案的基础上,设计了各自的编码方案.比如欧洲先后设计了EASCII和ISO/IEC 8859系列字符编码方案;为了显示中文及相关字符,中国大陆地区设计了GB系列编码.同样,日文、韩文以及其他世界各个国家和地区的文字都有它们各自的编码。
所有这些各个国家和地区所独立制定的既兼容ASCII又互相之间不兼容的字符编码,微软统称为ANSI编码。
所以,即使知道是ANSI编码,也还需要进一步知道具体是哪一个国家或地区的编码才能正确解码;而且,同一份文本,只能采用一种ANSI编码方案来编码,比如,无法用同一种ANSI编码来表示既有汉字、又有韩文的文本。
ANSI的字面意思并非某个字符编码方案,而是美国的一个非营利组织——美国国家标准学会(American National Standards Institute)的缩写。
ANSI这个组织做了很多标准的制定工作,包括前面介绍过的字符编码标准ASCII、C语言标准ANSI C,还有与各国和地区既兼容ASCII又互相不兼容的字符编码方案相对应的“代码页(Code Page)”标准。
注意代码页是针对ANSI编码下的一个概念,只在非Unicode编码下使用。
比如ANSI规定简体中文GB编码的代码页是936,即GBK,所以GB编码又叫做ANSI Code Page 936(ANSI标准的代码页936)。ISO 8859-1(即Latin-1)的代码页1252(即CP1252),各国和地区既兼容ASCII又互相不兼容的字符编码之所以被微软统称为ANSI编码的原因即在于此。
在微软Windows系统的编码处理中,ANSI编码一般代表系统默认的编码方式,而且并不是确定的某一种编码方式:
在简体中文操作系统中ANSI编码默认指的是GB系列编码(GB2312、GBK、GB18030);在繁体中文操作系统中ANSI编码默认指的是Big5编码(港澳台地区使用的繁体汉字编码);
在日文操作系统中ANSI编码默认指的是Shift JIS编码,等等
需要注意的是:代码页是字节实现字符-编码序列的映射表,是字符集在计算机中的具体编码实现,并不是像GB标准定义的机位码,而是字符和机内码的对应关系。计算机通过查表实现“字符-字节”之间的双向“翻译。
代码页主要用于具体实现各编码方案中的字符在计算机系统中的物理存储和显示。当计算机读取了一个二进制字节,那这个字节到底属于哪个字符,就需要到存储在计算机中的某个代码页中查找,这个查找的过程就被称为查表。
比如,当用户使用输入码(即外码)输入汉字时,输入法软件需要将输入码(出现重码时另加选择编号)根据代码页转换为机内码(即查表)进行存储,以及再根据机内码和相应的字体设定到对应的字体文件中查找字形码进行显示。
在Windows中,代码页是系统默认设置的(即默认系统区域设置),也可在(Windows7的)“控制面板-区域和语言-管理-非Unicode程序的语言-更改系统区域设置”中选择列表中的语言进行更改。
这个配置针对的是系统的非Unicode编解码配置,即在不使用Unicode编码的程序(即非Unicode程序)中输入和显示字符的默认编码方案**(显然主要是指ANSI编码方案**)和字体。为系统区域设置选择不同的语言,并不会影响Windows系统本身或其他使用Unicode编码方案的程序(即Unicode程序)的语言显示。
但是,很显然,如果同一个操作系统中,多个非Unicode程序采用了各不相同的ANSI编码,则同一时间只有一种ANSI编码的非Unicode程序的文字显示是正常的,采用其他ANSI编码的非Unicode程序的文字显示为乱码。而同一个非Unicode程序,是无法同时采用不同的ANSI编码的,比如同时采用中文和韩文,在非Unicode程序中是无法实现的,因为同一时间必定有其中之一是乱码的。不过,现在Unicode编码方案已经成为了主流,因此非Unicode程序已经难得一见了。
扩展:全角、半角
全角字符是中文显示及双字节中文编码的历史遗留问题。期的点阵显示器上由于像素有限,原先ASCII西文字符的显示宽度(比如8像素的宽度)用来显示汉字有些捉襟见肘(实际上早期的针式打印机在打印输出时也存在这个问题),因此就采用了两倍于ASCII字符的显示宽度(比如16像素的宽度)来显示汉字。
这样一来,ASCII西文字符在显示时其宽度为汉字的一半。或许是为了在西文字符与汉字混合排版时,让西文字符能与汉字对齐等视觉美观上的考虑,于是就设计了让西文字母、数字和标点等特殊字符在外观视觉上也占用一个汉字的视觉空间(主要是宽度),并且在内部存储上也同汉字一样使用2个字节进行存储的方案。这些与汉字在显示宽度上一样的西文字符就被称之为全角字符。
而原来ASCII中的西文字符由于在外观视觉上仅占用半个汉字的视觉空间(主要是宽度),并且在内部存储上使用1个字节进行存储,相对于全角字符,因而被称之为半角字符。
后来,其中的一些全角字符因为比较有用,就得到了广泛应用(比如全角的逗号“,”、问号“?”、感叹号“!”、空格“ ”等,这些字符在输入法中文输入状态下的半角与全角是一样的,英文输入状态下全角跟中文输入状态一样,但半角大约为全角的二分之一宽),专用于中日韩文本,成为了标准的中日韩标点字符。而其它的许多全角字符则逐渐失去了价值(现在很少需要让纯文本的中文和西文字符对齐了),就很少再用了。
现在全球字符编码的事实标准是Unicode字符集及基于此的UTF-8、UTF-16等编码实现方式。Unicode吸纳了许多遗留(legacy)编码,并且为了兼容性而保留了所有字符。因此中文编码方案中的这些全角字符也保留下来了,而国家标准也仍要求字体和软件都支持这些全角字符。不过,半角和全角字符的关系在UTF-8、UTF-16等中不再是简单的1字节和2字节的关系了。
3 Unicode编码方案
随着计算机发展到世界各地,于是各个国家和地区各自为政,搞出了很多既兼容ASCII但互相之间又不兼容的各种编码方案(微软统一称之为ANSI编码,具体体现为各种ANSI代码页)。同一个二进制编码在不同的ANSI编码方案中就有可能被解释成不同的字符,从而对采用不同ANSI编码方案的系统之间的数据交换和信息交流带来了极大的不便。比如大陆和台湾是只相隔150海里、使用着同一种语言的兄弟地区,也分别采用了不同的DBCS(Double Byte Character Set)双字节字符集编码方案。以前使用DOS操作系统的年代,大陆地区必须装上类似于“UCDOS希望汉字系统”这样的中文处理系统专门来处理采用GB类编码方案的汉字的显示、输入问题;而台湾地区由于采用BIG5编码方案(统一繁体字编码,俗称大五码,同样使用2个字节表示繁体汉字),则必须安装类似于“ET倚天汉字系统”这样的繁体中文处理系统才可以正确显示、输入采用BIG5编码方案的繁体汉字。因此,要想打开一个文本文件,就必须首先知道它所采用的ANSI编码方案,否则用错误的ANSI编码方案进行解码,就会出现乱码。
而且很要命的是,一个文件中,如果存在两种或两种以上采用不同的ANSI编码方案的字符,则同一时间只能显示其中的一种字符,要显示另一种,必须先切换操作系统的ANSI编码方案,或者加装额外的ANSI编码处理软件(不同的ANSI编码处理软件之间还很容易造成冲突)。为什么早期的电子邮件常常出现乱码?多半是因为发信人和收信人使用的操作系统所采用的ANSI编码方案不一样造成的。
想象一下,如果有一种统一的编码方案,将世界上所有字符都纳入其中,每一个字符都给予一个全球独一无二的编码,那么因为编码方案不同所造成的乱码,以及频繁切换编码方案等等问题,就统统都会消失了。
于是,在有识之士的推动下,全球所有国家和地区使用的所有字符的统一编码方案——Unicode/USC编码方案诞生了。字符编码方案的历史,也因此从单一ASCII编码方案的第一阶段,经由多个ANSI编码方案的第二阶段,发展到了当前的全球统一Unicode/UCS编码方案的第三阶段。
由Adobe、苹果、IBM、微软等世界上多家多语言软件开发商组成了统一码联盟 (The Unicode Consortium),于1991年发布了 The Unicode Standard (统一码标准),定义了一个全球统一的通用字符集,习惯简称为Unicode字符集。
注:Unicode字符集,常被称为统一码、万国码、单一码,严格来说,这些称呼都不够严谨或不够准确,因为Unicode字符集只是一个编号字符集CCS,尚未经过字符编码方式CEF和字符编码模式CES进行编码,称之为“码”,容易让人误解。
Unicode字符集的目标是涵盖目前人类使用的所有字符,并为每个字符分配一个唯一的字符编号(即码点编号、码点值)。目前,Unicode字符集将所有字符按照使用上的频繁度,被划分为了17个平面(Plane),每个平面上的编号空间有2^16=65536个码点。将来根据需要,还可扩展为更多平面。可以理解为17个二维数组构成的集合。
其中第0个平面,称为BMP(Basic Multilingual Plane,即基本多语言平面、基本多文种平面,往往简称为基本平面、平面0),基本涵盖了当今世界上正在使用中的常用字符。
我们平常用到的大多数常见字符,一般都是位于BMP平面上的。
BMP平面以外的其他平面称之为增补平面SP(Supplementary Plane,也称为辅助平面),目前共16个增补平面SP。
增补平面要么用来表示一些非常特殊的字符(比如不常用的象形文字、远古时期的文字等),多半只有专家在历史和科学领域里才会用到它们;要么被留作扩展之用,尚未被分配字符,称之为保留区。
目前Unicode字符集的17个平面中尚有大量的保留区编号空间未被使用。
Windows系统自NT开始,微软把所有的核心代码都改成了采用Unicode标准的版本(实际使用的就是Unicode标准的UTF-16字符编码方式CEF下的Little-Endian小端序字符编码模式CES,详见后文解释)。
因此,在这之后,Windows系统终于不需要再额外加装各种本土语言系统(比如“UCDOS希望汉字系统”、“ET倚天汉字系统”之类的),就可以直接显示全世界所有的字符了。
当然,为了保持向后的兼容性,对于之前的ANSI编码方案,Windows保留了对它们的支持。
Unicode在刚开始制订UTF-16字符编码时,并没有考虑与任何一种现有的字符编码保持完全兼容,比如GBK与Unicode在汉字的编码上是完全不一样的,没有任何一种简单的算法,可以将文本内容在UTF-16编码和GBK编码之间进行直接转换,要转换的话只能通过查表这样低效率的笨办法,一个字符对应一个字符地来进行。
即便是ASCII字符,也属于是不完全的间接兼容或半兼容,因为UTF-16编码也是用两个字节来表示ASCII字符的,虽然其低7位与ASCII编码保持了一致,其余高位的9位均只是占位的0,但毕竟还是使用了16位共两个字节,不同于ASCII的单字节编码。
正是鉴于此(当然除此之外还有其他原因),于是后来又设计了UTF-8字符编码方式,则实现了与ASCII编码的完全兼容(后文有详细解释)。
**从字符集的角度上来讲,Unicode字符集不同于ASCII这样不能再增加字符的封闭字符集,而是一个开放字符集,是可以不断地增加字符的。**因此,Unicode字符集也在不断发展中(比如随着互联网即时聊天工具的发展而流行起来的很多Emoji表情符,就被不断地增加到了Unicode字符集里),理论上支持的字符数量是没有上限的,未来还可不断地扩展。
Unicode字符集给每个字符根据其所在的码点分配了一个唯一的码点值(即码点编号,可认为是字符编号。
同时,还给每个码点赋予了一个正式的名称:在表示一个Unicode码点编号(或UCS码点编号)的十六进制数的前面加上“U+”,称之为码点名称,或字符名称(考虑到代理区、保留区等特殊区域中的码点实际上并未分配字符,因此严格来讲应称为“码点名称”更为合适,但很多文章中都习惯称为“字符名称”)。
比如,U+0041这个码点名称,表示英语大写字母A,U+4E25这个码点名称,表示汉字“严”。具体的码点名称与字符的对应表,可以查询字符和编号映射表(字符集),其中汉字部分也可查询专门中日韩汉字Unicode字符和编号映射表(字符集)。
其中,Unicode字符集中的U+0000-U+007F(即十进制的0-127),跟ASCII字符集(即ISO/IEC 646标准)是一致的;U+0000-U+00FF(即十进制的0~255),跟ISO/IEC 8859-1字符集(即Latin-1字符集)也是一致的
3.1最开始出现的编码方式为UTF-16:
一个字符集一般可以用一张或多张由多个行和多个列所构成的二维表来表示,二维表中行与列相交的点,称之为码点(Code Point代码点),也称之为码位(Code position代码位);每个码点分配一个唯一的编号,称之为码点值或码点编号,除开某些特殊区域(比如代理区、专用区)的非字符码点和保留码点,每个码点唯一对应于一个字符。因此,除开非字符码点和保留码点,码点值(即码点编号)通常来说就是其所对应的字符的编号,所以码点值有时也可以直接称之为字符编号,虽然不够准确,但更为直接。随着Unicode字符集的不断增补扩大(比如现在的Unicode字符集至少需要21位才能全部表示),码点值也扩展为用三个字节或以上的十六进制数字表示。目前Unicode标准中,将字符按照一定的类别划分到0~16这17个平面(Plane层面)中,每个平面中拥有2^16 = 65536个码点,因此,目前Unicode字符集所拥有的码点总数,也就是Unicode的编号空间为17*65536=1114112。
三种码元对应就有了Unicode字符编号的三种UTF编码方式(即Unicode码转换格式Unicode Transformation Format,或称通用字符集转换格式UCS Transformation Format):
UTF-8,即8-bit Unicode/UCS Transformation Format;
UTF-16,即16-bit Unicode/UCS Transformation Format;
UTF-32,即32-bit Unicode/UCS Transformation Format。
或者反过来说,Unicode字符编号的三种UTF编码方式(UTF-8、UTF-16、UTF-32)分别采用了不同的码元(单字节、双字节、四字节)来编码。
这篇关于字符编码二(各类编码方式的发展、半角和全角)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!