字符集和字符编码(CharsetEncoding)
——每个软件开发⼈员应该⽆条件掌握的知识!
——Unicode伟⼤的创想!
相信⼤家⼀定碰到过,打开某个⽹页,却显⽰⼀堆像乱码,如"бЇЯАзЪСЯ"、"�????????"?还记得HTTP中的Accept-Charset、Accept-Encoding、Accept-Language、Content-Encoding、Content-Language等消息头字段?这些就是接下来我们要探讨的。
⽬录:
1.*础知识
计算机中储存的信息都是⽤⼆进制数表⽰的;⽽我们在屏幕上看到的英⽂、汉字等字符是⼆进制数转换之后的结果。通俗的说,按照何种规则将字符存储在计算机中,如'a'⽤什么表⽰,称为"编码";反之,将存储在计算机中的⼆进制数解析显⽰出来,称为"解码",如同密码学中的加密和解密。在解码过程中,如果使⽤了错误的解码规则,则导致'a'解析成'b'或者乱码。
字符集(Charset):是⼀个系统⽀持的所有抽象字符的集合。字符是各种⽂字和符号的总称,包括各国家⽂字、标点符号、图形符号、数字等。
字符编码(Character Encoding):是⼀套法则,使⽤该法则能够对⾃然语⾔的字符的⼀个集合(如字母表或⾳节表),与其他东西的⼀个集合(如号码或电脉冲)进⾏配对。即在符号集合与数字系统之间建⽴对应关系,它是信息处理的⼀项*本技术。通常⼈们⽤符号集合(⼀般情况下就是⽂字)来表达信息。⽽以计算机为*础的信息处理系统则是利⽤元件(硬件)不同状态的组合来存储和处理信息的。元件不同状态的组合能代表数字系统的数字,因此字符编码就是将符号转换为计算机可以接受的数字系统的数,称为数字代码。
2.常⽤字符集和字符编码
常见字符集名称:ASCII字符集、GB2312字符集、BIG5字符集、GB18030字符集、Unicode字符集等。计算机要准确的处理各种字符集⽂字,需要进⾏字符编码,以便计算机能够识别和存储各种⽂字。
2.1. ASCII字符集&编码
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是*于的⼀套系统。它主要⽤于显⽰,⽽其扩展版本EASCII则可以勉强显⽰其他。它是现今最通⽤的单编码系统(但是有被Unicode追上的迹象),并等同于国际标准ISO/IEC 646。ASCII字符集:主要包括控制字符(回车键、退格、换⾏键等);可显⽰字符(英⽂⼤⼩写字符、阿拉伯数字和西⽂符号)。
ASCII编码:将ASCII字符集转换为计算机可以接受的数字系统的数的规则。使⽤7位(bits)表⽰⼀个字符,共128字符;但是7位编码的字符集只能⽀持128个字符,为了表⽰更多的常⽤字符对ASCII进⾏了扩展,ASCII扩展字符集使⽤8位(bits)表⽰⼀个字符,共256字符。ASCII字符集映射到数字编码规则如下图所⽰:
图1 ASCII编码表
图2 扩展ASCII编码表
ASCII的最⼤缺点是只能显⽰26个*本拉丁字母、阿拉伯数⽬字和英式标点符号,因此只能⽤于显⽰现代美国英语(⽽且在处理英语当中的外来词如naïve、café、élite等等时,所有重⾳符号都不得不去掉,即使这样做会违反拼写规则)。⽽EASCII虽然解决了部份西欧语⾔的显⽰
中文字符unicode查询
问题,但对更多其他语⾔依然⽆能为⼒。因此现在的苹果电脑已经抛弃ASCII⽽转⽤。
2.2. GBXXXX字符集&编码
计算机发明之处及后⾯很长⼀段时间,只⽤应⽤于美国及西⽅⼀些发达国家,ASCII能够很好满⾜⽤户的需求。但是当天朝也有了计算机之后,为了显⽰中⽂,必须设计⼀套编码规则⽤于将汉字转换为计算机可以接受的数字系统的数。
天朝专家把那些127号之后的奇异符号们(即EASCII)取消掉,规定:⼀个⼩于127的字符的意义与原来相同,但两个⼤于127的字符连在⼀起时,就表⽰⼀个汉字,前⾯的⼀个字节(他称之为⾼字节)从0xA1⽤到 0xF7,后⾯⼀个字节(低字节)从0xA1到0xFE,这样我们就可以组合出⼤约7000多个简体汉字了。在这些编码⾥,还把数学符号、罗马希腊的字母、⽇⽂的假名们都编进去了,连在ASCII⾥本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全⾓"字符,⽽原来在127号以下的那些就叫"半⾓"字符了。
上述编码规则就是GB2312。GB2312或GB2312-80是,全称《信息交换⽤汉字编码字符集·*本集》,⼜称,由发布,实施。GB2312编码通⾏于中国⼤陆;等地也采⽤此编码。中国⼤陆⼏乎所有的中⽂系统和国际化的软件都⽀持GB2312。GB2312的出现,*本满⾜了汉字的计算机处理需要,它所收录的汉字已经覆盖中国⼤陆99.75%的使⽤频率。对于、等⽅⾯出现的,GB2312不能处理,这导致了后来及汉字字符集的出现。下图是GB2312编码的开始部分(由于其⾮常庞⼤,只列举开始部分,具体可查看):
图3 GB2312编码表的开始部分
由于只收录6763个汉字,有不少汉字,如部分在GB 2312-80推出以后才简化的汉字(如"啰"),部分⼈名⽤字(如中国前总理的"*"字),台湾及⾹港使⽤的,及汉字等,并未有收录在内。于是⼚商微软利⽤GB 2312-80未使⽤的编码空间,收录GB 13000.1-93全部字符制定了GBK编码。根据资料,GBK是对GB2312-80的扩展,也就是字码表 (Code Page 936)的扩展(之前CP936和GB 2312-80⼀模⼀样),最早实现于简体中⽂版。虽然GBK收录的全部字符,但编码⽅式并不相同。GBK⾃⾝并⾮国家标准,只是曾由标准化司、科技与质量监督司公布为"技术规范指导性⽂件"。原始GB13000⼀直未被业界采⽤,后续国家标准技术上兼容GBK⽽⾮GB13000。
GB 18030,全称:GB 18030-2005《信息技术中⽂编码字符集》,是现时最新的内码字集,是GB 18030-2000《信息技术信息交换⽤汉字编码字符集 *本集的扩充》的修订版。与完全兼容,与*本兼容,⽀持及的全部统⼀汉字,共收录汉字70244个。GB 18030主要有以下特点:
与相同,采⽤多编码,每个字可以由1个、2个或4个字节组成。
编码空间庞⼤,最多可定义161万个字符。
⽀持中国国内的⽂字,不需要动⽤造字区。
汉字收录范围包含繁体汉字以及⽇韩汉字
图4 GB18030编码总体结构
本规格的初版使中华⼈民共和国信息产业部电⼦⼯业标准化研究所起草,由国家质量技术监督局于发布。现⾏版本为国家质量监督检验总局和中国国家标准化管理委员会于发布,实施。此规格为在中国境内所有软件产品⽀持的强制规格。
2.3. BIG5字符集&编码
Big5,⼜称为⼤五码或五⼤码,是使⽤(正体中⽂)社区中最常⽤的电脑标准,共收录13,060个汉字。中⽂码分为及两类,Big5属中⽂内码,知名的中⽂交换码有、。Big5虽普及于、与等繁体中⽂通⾏区,但长期以来并⾮当地的国家标准,⽽只是。、等主要系统的字符集都是以Big5为*准,但⼚商⼜各⾃增加不同的造字与造字区,派⽣成多种不同版本。,Big5被收录到CNS11643中⽂标准交换码的附录当中,取得了较正式的地位。这个最新版本被称为Big5-2003。
Big5码是⼀套,使⽤了双⼋码存储⽅法,以两个字节来安放⼀个字。第⼀个字节称为"⾼位字节",第⼆个字节称为"低位字节"。"⾼位字节"使⽤了0x81-0xFE,"低位字节"使⽤了0x40-0x7E,及0xA1-0xFE。在Big5的分区中:
0x8140-0xA0FE保留给⽤户⾃定义字符(区)
0xA140-0xA3BF、希腊字母及特殊符号,包括在0xA259-0xA261,安放了九个计量
⽤汉字:兙兛兞兝兡兣嗧瓩糎。
0xA3C0-0xA3FE保留。此区没有开放作造字区⽤。
0xA440-0xC67E,先按笔划再按部⾸排序。
0xC6A1-0xC8FE保留给⽤户⾃定义字符(造字区)
0xC940-0xF9D5,亦是先按笔划再按部⾸排序。
0xF9D6-0xFEFE保留给⽤户⾃定义字符(造字区)
Unicode字符集&UTF编码
3.伟⼤的创想Unicode
——不得不单独说Unicode
像天朝⼀样,当计算机传到世界各个国家时,为了适合当地语⾔和字符,设计和实现类似GB232/GBK/GB18030/BIG5的编码⽅案。这样各搞⼀套,在本地使⽤没有问题,⼀旦出现在⽹络中,由于不兼容,互相访问就出现了乱码现象。
为了解决这个问题,⼀个伟⼤的创想产⽣了——Unicode。Unicode编码系统为表达任意语⾔的任意字符⽽设计。它使⽤4字节的数字来表达每个字母、符号,或者表意⽂字(ideograph)。每个数字代表唯⼀的⾄少在某种语⾔中使⽤的符号。(并不是所有的数字都⽤上了,但是总数已经超过了65535,所以2个字节的数字是不够⽤的。)被⼏种语⾔共⽤的字符通常使⽤相同的数字来编码,除⾮存在⼀个在理
的语源学(etymological)理由使不这样做。不考虑这种情况的话,每个字符对应⼀个数字,每个数字对应⼀个字符。即不存在⼆义性。不再需要记录"模式"了。U+0041总是代表'A',即使这种语⾔没有'A'这个字符。
在领域中,Unicode(统⼀码、万国码、单⼀码、标准万国码)是业界的⼀种标准,它可以使电脑得以体现世界上数⼗种⽂字的系统。Unicode 是*于(Universal Character Set)的标准来发展,并且同时也以书本的形式对外发表。Unicode 还不断在扩增,每个新版本插⼊更多新的字符。直⾄⽬前为⽌的第六版,Unicode 就已经包含了超过⼗万个(在,Unicode 的第⼗万个字符被采纳且认可成为标准之⼀)、⼀组可⽤以作为视觉参考的代码图表、⼀套编码⽅法与⼀组标准、⼀套包含了上标字、下标字等字符特性的枚举等。Unicode 组织(The Unicode Consortium)是由⼀个⾮营利性的机构所运作,并主导 Unicode 的后续发展,其⽬标在于:将既有的字符编码⽅案以Unicode 编码⽅案来加以取代,特别是既有的⽅案在多语环境下,皆仅有有限的空间以及不兼容的问题。
(可以这样理解:Unicode是字符集,UTF-32/ UTF-16/ UTF-8是三种字符编码⽅案。)
3.1.UCS & UNICODE
通⽤字符集(Universal Character Set,UCS)是由制定的ISO 10646(或称ISO/IEC 10646)标准所定义的标准字符集。历史上存在两个独⽴的尝试创⽴单⼀字符集的组织,即国际标准化组织(ISO)
和多语⾔软件制造商组成的。前者开发的 ISO/IEC 10646 项⽬,后者开发的项⽬。因此最初制定了不同的标准。
前后,两个项⽬的参与者都认识到,世界不需要两个不兼容的字符集。于是,它们开始合并双⽅的⼯作成果,并为创⽴⼀个单⼀编码表⽽协同⼯作。从Unicode 2.0开始,Unicode采⽤了与ISO 10646-1相同的字库和字码;ISO也承诺,ISO 10646将不会替超出
U+10FFFF的UCS-4编码赋值,以使得两者保持⼀致。两个项⽬仍都存在,并独⽴地公布各⾃的标准。但统⼀码联盟和ISO/IEC
JTC1/SC2都同意保持两者标准的码表兼容,并紧密地共同调整任何未来的扩展。在发布的时候,Unicode⼀般都会采⽤有关字码最常见的字型,但ISO 10646⼀般都尽可能采⽤。
3.2.UTF-32
上述使⽤4字节的数字来表达每个字母、符号,或者表意⽂字(ideograph),每个数字代表唯⼀的⾄少在某种语⾔中使⽤的符号的编码⽅案,称为UTF-32。UTF-32⼜称UCS-4是⼀种将字符编码的协定,对每个字符都使⽤4字节。就空间⽽⾔,是⾮常没有效率的。
这种⽅法有其优点,最重要的⼀点就是可以在常数时间内定位字符串⾥的第N个字符,因为第N个字符
从第4×Nth个字节开始。虽然每⼀个码位使⽤固定长定的字节看似⽅便,它并不如其它Unicode编码使⽤得⼴泛。
3.3.UTF-16
尽管有Unicode字符⾮常多,但是实际上⼤多数⼈不会⽤到超过前65535个以外的字符。因此,就有了另外⼀种Unicode编码⽅式,叫做UTF-16(因为16位 = 2字节)。UTF-16将0–65535范围内的字符编码成2个字节,如果真的需要表达那些很少使⽤的"星芒层(astral plane)"内超过这65535范围的Unicode字符,则需要使⽤⼀些诡异的技巧来实现。UTF-16编码最明显的优点是它在空间效率上⽐UTF-32⾼两倍,因为每个字符只需要2个字节来存储(除去65535范围以外的),⽽不是UTF-32中的4个字节。并且,如果我们假设某个字符串不包含任何星芒层中的字符,那么我们依然可以在常数时间内到其中的第N个字符,直到它不成⽴为⽌这总是⼀个不错的推断。其编码⽅法是:
如果字符编码U⼩于0x10000,也就是⼗进制的0到65535之内,则直接使⽤两字节表⽰;
如果字符编码U⼤于0x10000,由于UNICODE编码范围最⼤为0x10FFFF,从0x10000到0x10FFFF之间共有0xFFFFF个编码,也就是需要20个bit就可以标⽰这些编码。⽤U'表⽰从0-0xFFFFF之间的值,将其前 10 bit作为⾼位和16 bit的数值0xD800进⾏逻辑or 操作,将后10 bit作为低位和0xDC00做逻辑or 操作,这样组成的 4个byte就构成了U的编码。
对于UTF-32和UTF-16编码⽅式还有⼀些其他不明显的缺点。不同的计算机系统会以不同的顺序保存字节。这意味着字符U+4E2D在UTF-16编码⽅式下可能被保存为4E 2D或者2D 4E,这取决于该系统使⽤的是⼤尾端(big-endian)还是⼩尾端(little-endian)。(对于UTF-32编码⽅式,则有更多种可能的字节排列。)只要⽂档没有离开你的计算机,它还是安全的——同⼀台电脑上的不同程序使⽤相同的字节顺序(byte order)。但是当我们需要在系统之间传输这个⽂档的时候,也许在万维⽹中,我们就需要⼀种⽅法来指⽰当前我们的字节是怎样存储的。不然的话,接收⽂档的计算机就⽆法知道这两个字节4E 2D表达的到底是U+4E2D还是U+2D4E。
为了解决这个问题,多字节的Unicode编码⽅式定义了⼀个"字节顺序标记(Byte Order Mark)",它是⼀个特殊的⾮打印字符,你可以把它包含在⽂档的开头来指⽰你所使⽤的字节顺序。对于UTF-16,字节顺序标记是U+FEFF。如果收到⼀个以字节FF FE开头的UTF-16编码的⽂档,你就能确定它的字节顺序是单向的(one way)的了;如果它以FE FF开头,则可以确定字节顺序反向了。
3.4.UTF-8
UTF-8(8-bit Unicode Transformation Format)是⼀种针对的可变长度(),也是⼀种。它可以⽤来表⽰Unicode标准中的任何字符,且其编码中的第⼀个仍与兼容,这使得原来处理ASCII字符的⽆须或只须做少部份修改,即可继续使⽤。因此,它逐渐成为、及其他或传送⽂字的应⽤中,优先采⽤的编码。(IETF)要求所有都必须⽀持UTF-8编码。
UTF-8使⽤⼀⾄四个为每个字符编码:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。