谈到字符编码,一大串名词接踵而来:ASCII,GB2312,GBK,BIG5,Unicode,UTF-8……真是让人眼花缭乱,不知所措。花了一个下午的时间,终于大致弄明白了它们之间的渊源,现在把我所理解的写下来。当然了,这只是我个人的理解,也不一定全部都是正确的,如果对某些内容有怀疑,可以查看参考网页,网址在最后面给出。
字符编码
首先应该明确一下什么是字符编码( Encoding )。简单来讲,字符编码就是把现实生活中使用的各种文字符号映射为计算机中的二进制数据。编码的方式有很多种。
字符集
一组有某种联系的字符组成字符集,例如,英文字符集,汉字字符集。每一种字符编码方式都与一种字符集相关联,也就是说每一种编码方式针对一种字符集,是一一对应的关系。所以后面所说的字符集跟编码这两个概念可以互换。
ASCII字符集
对于这个字符集大家都不会陌生,它是使用最广泛的字符集。其编码方式规定,一个字符使用一个字节来表示,而且只使用低 7 位,最高位用作奇偶校验,所以 ASCII 字符集只有 128 个字符。它被国际标准化组织 (ISO) 定为国际标准,称为 ISO 646 标准。
扩展ASCII字符集
标准 ASCII 字符集只有 128 个字符,用于英语完全足够,然而,全世界有上百种语言,这 128 个字符显得如此寒酸。注意到 ASCII 编码方式中最高位是不使用的,于是有人将其纳入使用,使字符的个数上升到 256 个,然而,如何使用这扩充出来的 128 个字符,每个开发者都有自己的意见。于是, ISO 8859 标准诞生了。该标准定义了前 128 个字符仍然是标准的 ASCII 字符集,而后 128 个字符可以使用不用的字符集。该标准为后面 128 个字符制定了多个字符集:
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-8-I - 希伯来语 ( 逻辑顺序 )
ISO 8859-9 (Latin-5 或 Turkish) - 它把 Latin-1 的冰岛语字母换走,加入土耳其语字母。
ISO 8859-10 (Latin-6 或 Nordic) - 北日耳曼语支,用来代替 Latin-4 。
ISO 8859-11 (Thai) - 泰语,从泰国的 TIS620 标准字集演化而来。
ISO 8859-13 (Latin-7 或 Baltic Rim) - 波罗的语族
ISO 8859-14 (Latin-8 或 Celtic) - 凯尔特语族
ISO 8859-15 (Latin-9) - 西欧语言,加入 Latin-1 欠缺的法语及芬兰语重音字母,以及欧元符号。
ISO 8859-16 (Latin-10) - 东南欧语言。主要供罗马尼亚语使用,并加入欧元符号。
此即扩展 ASCII 字符集。
双字节字符集DBCS(Double byte character set)
虽然扩展 ASCII 字符集解决了大部分西方语言的问题,但在遥远的东方,问题比这严重得多。单单汉字就有几万个,再加上日文和韩文,这个数量更大了。为了解决这个问题,各种汉字编码应运而生,例如 GB2312 , GBK , BIG5 等。实际上,这些汉字编码的工作方式跟扩展 ASCII 字符集差不多,它们都是使用了后面的 128 个字符。不同的是,汉字编码使用两个字节来表示一个字符,这两个字节分别称为 “ 首字节 ” 和 “ 跟随字节 ” 。首字节的取值范围不多于 128 个(实际上用不着 128 个值),跟随字节的取值可以是任意的。也就是说,使用首字节来匹配后面的 128 个位置。在读取文本的时候,如果读到了首字节的值,就与它后面那个字节一起解释成中文字符。
可以认为,这些汉字编码都属于扩展 ASCII 字符集。
GB2312 是最早制定的汉字字符集,属于简体字符集,简称 “ 国标码 ” ;而 BIG5 属于繁体字符集。 GB2312 所支持的汉字太少,于是制定了汉字扩展规范 GBK ,收录了更多的汉字。
代码页(Code Page)
由上面的内容可知,存在如此多的字符集,那么什么时候应该使用哪种字符集呢?操作系统使用了代码页的概念。每种代码页对应一种字符集,使用哪种代码页也就意味着使用了哪种字符集。要改变系统当前使用的代码页,可以在控制面板的区域和语言选项中更改。很多乱码问题就是由于代码页与所显示的文本使用的字符集不匹配。
Unicode
双字节字符集虽然解决了汉字的显示问题,但是处理这样的字符串确实非常麻烦,因为在这样的字符串中根本不知道其中有多少个字符。要处理这样的字符串,必须从头开始分析,确定哪个是首字节的值。这种处理方式极为笨拙,而且效率低下。由此产生了 Unicode 字符集规范。 Unicode 字符集一律以两个字节来表示一个字符,所以它最多可以表示 65536 个字符,可以囊括世界上所有的语言字符。由于处理 Unicode 字符串极为简便,而且它可以表示世界上的任意字符,所以包括 C# , Java 在内的编程语言中,所有字符串一律使用 Unicode 编码。而 Windows 操作系统的内核早在 NT 时代就已经支持 Unicode 编码。
通用字符集UCS(Universal Character Set )
这个字符集被提得比较少,不过它与 Unicode 字符集一样,目的也是为了囊括世界上所有语言的文字。 UCS 是 ISO 颁布的 10646 号标准( Unicode 不是 ISO 标准),有 UCS-2 和 UCS-4 等编码方式,其中的 “2” 和 “4” 指的是使用多少个字节表示一个字符。就目前而言,在 UCS-2 码之前补上两个零字节,便可得到相对应的 UCS-4 码。 Unicode 编码可以与 UCS 编码兼容。
UTF-8
Unicode 编码规定一个字符由两个字节表示,这对于东方的程序员来说是好事,但对于西方程序员来说就不那么讨好了,因为如果使用 Unicode 的话,他们的字符串所需的容量会增加一倍。于是又催生了 UTF-8 编码。 UTF 全称是 UCS Transformation Format ,由名称来看,它是用于 UCS 的传输格式,这种说法让人迷惑。其实完全可以把 UTF-8 看成是 UCS 的一种压缩编码,它使用独特的算法压缩使用 UCS 编码的数据,使其更利于在网络上传输。由于 Unicode 与 UCS 兼容,所以也可以把 UTF-8 看成是对 Unicode 编码的压缩。
使用 UTF-8 编码,可以使原本只需一个字节的字符使用单字节来存储,但是却会使用三个字节来存储中文、韩文等字符。可见这种 “ 压缩 ” 只是对英文字符的压缩。
除了 UTF-8 ,还有 UTF-7 、 UTF-16 、 UTF-32 等编码,其中 UTF-16 就是使用两个字节表示一个字符的标准 Unicode 编码。目前使用最广泛的编码格式是 UTF-8 。
参考网页:
http://blog.csdn.net/zfive5/articles/619128.aspx
http://hideto.javaeye.com/blog/97803
最后在说明一下,以上内容仅为个人理解,错误在所难免,如有发现请提出哦。。另外这些只是非常浅显的内容,如果想要了解更多,请浏览参考网页并积极地百度或 Google.