关于字符编码笔记
1.概述
计算机最开始只有一种编码,就是ASCII编码,毕竟计算机是老美发明的,当时也不会考虑到其他国家的语言。但是由于计算机在全世界不断发展,ASCII编码的弊端逐步呈现出来,随之而来的就是各种国家都为自己的语言制定了一种or多种编码。但是这样没有一种统一的编码,在交互的时候会非常难以适配,所以最终为了世界大一统,有了unicode编码。
2.ASCII编码
首先说一下,一个字节(1 Byte)一共是8(bits),用十六进制表示是0xXY,其取值范围符合正则表达式:[0x([a-f]|[A-F]|[0-9]){2,2}]。
ASCII编码只用了一个字节的0x00 - 0x7F,0x80 - 0xFF是没有使用的。所以ASCII编码最多就只能表示128个(0x00 - 0x7F)字符,其中包含英文字母,一些可见符号(惊叹号、句号等)和不可见符号(回车符、换行符等)。
3.ANSI编码(亦或ANSI标准)
后来为了突破ASCII编码的限制,为了支持更多的语言,就制定了ANSI编码。
ANSI编码采用了ASCII编码没有使用的0x80 - 0xFF域范围,但是这还不行,因为这个范围也只有128种不同值。举例来说,中国简体汉字,就有几千个不同字符(汉字+中文标点符号)那么128是远远不够的,于是ANSI就把字符表达方式扩充至两个字节(2 Bytes),那么这样就有了128*128种取值范围了。
ANSI因为没有采用0x00 - 0x7F值域,所以ANSI是兼容ASCII编码的。
但是ANSI依然做得不好,因为ANSI不是具体指某一种编码,而是一套标准,规定每个不同国家不同地区自己可以按照ANSI标准自行制定符合本国语言的编码方式,前提条件就是不要使用0x00 - 0x7F即可。
所以说,与其说ANSI是一套编码,不如说ANSI是一套标准。众所周知,标准只会规定一些大框框,具体实现起来各有不同。正因为如此每个国家实现自己的ANSI标准时就创造了多种不同的编码方式。
再说一点,不同的ANSI标准的编码实现,互相之间一般是不兼容的。如果试图把不同ANSI编码的文档存储在同一个文本文件中,那么结果将是无法正确解读这个文档。例如中文的ANSI标准实现有GB2312编码、BIG5编码,日文的ANSI编码有JIS编码。
3.1.GB2312编码
全称是《信息交换用汉字编码字符集——基本集》,由国家标准总局发布于1980年,1981年05月01日正式实施,通行于中国大陆地区。因为它的标准号是GB 2312 - 1980,所以就称呼它为GB2312编码。
GB2312收录了汉字6763个和非汉字图形字符682个(有拉丁字母、希腊字母、日文平假名及片假名、俄语西里尔字母)。它收录的汉字和非汉字图形字符覆盖了在中国大陆地区99.75%的使用频率。
GB2312依然不完美,虽然将近99%的覆盖率,还是没有100%。GB2312对于古汉语或者人名中出现的罕见字不能识别。
3.2.GBK编码
正因为GB2312的不完美,所以有了GBK的出现。
GBK全称:汉字内码扩展规范,K其实是扩展的扩的首字母的意思。英文全称:Chinese Internal Code Specification。
GBK收录了21003个汉字(包括简体字、繁体字),符号883个。
3.3.GB18030编码
GB18030编码现在正在不断更新,第一版本是2000年发布的。截至目前最新的有GB18030-2005编码标准,也就是2005年发布的。
GBK还不完美?对,它不支持少数名族文字,例如:藏文、朝鲜文、维吾尔文等。
GB18030收录了近70,000个汉字。采用三种方式:单字节(ASCII编码)、双字节、四字节。
3.4.BIG5编码(大五码)
BIG5编码,又称大五码,适用于台湾、香港地区。
玩游戏的童鞋肯定有感触,90年代很多好玩的RPG游戏都是台湾公司制作的,当然他们采用当然就是BIG5编码了,于是在大陆的简体中文操作系统中就显示不正确了。
3.5.总结
从这些也能看出想要使用ANSI来收录全世界所有语言的所有字符是不可能的。国际标准化组织岂能坐视不管?试想,要是不创造一种大一统的编码方式,那在互联网盛行的今天会粗大事儿的。
4.统一的编码
之前也说到,不同的ANSI编码放在同一文本内,会造成无法解读的尴尬。那是因为同一个编码值在不同的ANSI编码中代表不同的字,那是解读成这个字,还是那个字呢?这样混乱就出现了。
那么势必要出现一种统一的编码,它应该具备如下特性:
1.完整性,囊括世界上已知的所有语言的所有字符。
2.唯一性,每一个不同的字符都有唯一的编码值对应,整个字符集中无重复记录。
3.可扩展性,如果又发现新的字符,需要在不影响之前已有编码值的情况下进行字符集扩充。
4.只有一个统一的组织对它进行维护、扩展升级。
但是事实上,前3条都满足了。唯独第4条不满足。
我想告诉你,世界上曾经有两个组织,都试图创造一个唯一的字符集,来满足以上特性。于是他们谁也不服谁,走出了两条分支,他们分别是“国际标准化组织(ISO)”和多语言软件制造商组成的“统一码联盟”。
4.1.Unicode编码
由unicode.org(统一码联盟)制定。
4.2.UCS编码
由ISO(国际标准化组织)制定。
4.3.合二为一
1991年,这两个组织终于发现,其实这个世界上不需要维护两套唯一标准字符集,于是他们决定开展合作,虽然还是各自发展,但是一定会做到两者互相兼容。
5.UTF编码
前面说了不管是UCS编码还是Unicode编码,都会在存储上浪费一定空间,于是产生了UTF编码(Unicode/UCS Transformation Format)。
UTF编码有多种编码方式:UTF-8、UTF-16、UTF-32。
5.1.UTF-8编码
最常见的是UTF-8编码,它是变长编码方式,兼容ASCII编码,对于其他字符,每个字符占用1-3个字节,所以它很省空间。它与CPU字节序无关,不管是大端还是小端,适用于不同芯片平台。容错能力高,一个字节损坏,只会影响包含该字节的编码字符,不会产生连锁反应。
所以sizeof(UTF-8 str) <= sizeof(ANSI str) * 1.5,就是说同一串内容,用UTF-8去编码,那么占用字节数最多不超过ANSI编码方式的1.5倍。
6.总结
作为软件研发人员,我感觉上面这些知识确实要知道,最好是这样梳理一遍。
每个不同国家不同语言的开发者,至少要了解当地的ANSI编码是哪种实现形式(比如中文ANSI是:GB2313或者GBK)以及UTF-8编码。当遇到软件国际化的问题,自然就得心应手了。
我是通过很多资料,综合阅读、对比才总结出上述内容。