字符编码相关概念理解

来源:互联网 发布:手机号正则表达式js 编辑:程序博客网 时间:2024/06/01 08:15

写在前面。字符编码是一个让人头疼的问题,让问题显得混淆的原因不止在于编码本身的多样性和发展变化,更在于人们对于其中所涉及的术语概念的滥用。本文所提到的术语概念是在查阅相关资料以及文献汇总得到的,注重于对编码所涉及的问题的梳理。

一、基本概念

字符集:一个国家或地区,或者某种语言文字中所使用的所有符号的集合。如中国字符集指的就是“汉字”和标点。

字符编码:一个从字符集到一个非负整数集合直接的一一映射,经常使用一个表格给出。

字符编码算法:把字符对应的字符编码映射为八位组序列的方法。

注:有的文献也将字符编码和字符编码算法统称为“编码”,即规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储。事实上,各个国家和地区在制定编码标准的时候,“字符编码”和“编码算法”一般都是同时制定的。因此,平常我们所说的“字符编码”,比如:GB2312, GBK, JIS 等,除了有“字符的集合”这层含义外,同时也包含了“编码方法”的含义。

二、字符编码发展阶段

从计算机对多国语言的支持角度看,字符编码的发展大致可以分为三个阶段(下表出处见参考资料2):

 系统内码说明系统阶段一ASCII计算机刚开始只支持英语,其它语言不能够在计算机上存储和显示。英文 DOS阶段二ANSI编码
(本地化)为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。

不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。

不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。中文 DOS,中文 Windows 95/98,日文 Windows 95/98阶段三UNICODE
(国际化)为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。Windows NT/2000/XP,Linux,Java


理解编码的关键,还要把字符的概念和字节的概念理解准确。这两个概念容易混淆,我们在此做一下区分(参考资料2):

 概念描述举例字符人们使用的记号,抽象意义上的一个符号。'1', '中', 'a', '$', '¥', ……字节计算机中存储数据的单元,一个8位的二进制数,是一个很具体的存储空间。0x01, 0x45, 0xFA, ……ANSI
字符串在内存中,如果“字符”是以 ANSI 编码形式存在的,一个字符可能使用一个字节或多个字节来表示,那么我们称这种字符串为 ANSI 字符串或者多字节字符串。"中文123"
(占7字节)UNICODE
字符串在内存中,如果“字符”是以在 UNICODE 中的序号存在的,那么我们称这种字符串为 UNICODE 字符串或者宽字节字符串。L"中文123"
(占10字节)

由于不同 ANSI 编码所规定的标准是不相同的,因此,对于一个给定的多字节字符串,我们必须知道它采用的是哪一种编码规则,才能够知道它包含了哪些“字符”。也就是说,以字节形式存在的字符串,必须知道是哪种编码才能被正确地使用。而对于 UNICODE 字符串来说,是以字符的“序号”来存储的,不管在什么环境下,它所代表的“字符”内容总是不变的。

三、具体实例

在这里,我们根据编码规则的特点,把所有的编码分成三类(同样来自资料2):

分类编码方法说明单字节字符编码ISO-8859-1最简单的编码规则,每一个字节直接作为一个 UNICODE 字符。比如,[0xD6, 0xD0] 这两个字节,通过 iso-8859-1 转化为字符串时,将直接得到 [0x00D6, 0x00D0] 两个 UNICODE 字符,即 "ÖÐ"。

反之,将 UNICODE 字符串通过 iso-8859-1 转化为字节串时,只能正常转化 0~255 范围的字符。ANSI 编码GB2312,
BIG5,
Shift_JIS,
ISO-8859-2 ……把 UNICODE 字符串通过 ANSI 编码转化为“字节串”时,根据各自编码的规定,一个 UNICODE 字符可能转化成一个字节或多个字节。

反之,将字节串转化成字符串时,也可能多个字节转化成一个字符。比如,[0xD6, 0xD0] 这两个字节,通过 GB2312 转化为字符串时,将得到 [0x4E2D] 一个字符,即 '中' 字。

“ANSI 编码”的特点:
1. 这些“ANSI 编码标准”都只能处理各自语言范围之内的 UNICODE 字符。
2. “UNICODE 字符”与“转换出来的字节”之间的关系是人为规定的。UNICODE 编码UTF-8,
UTF-16, UnicodeBig ……与“ANSI 编码”类似的,把字符串通过 UNICODE 编码转化成“字节串”时,一个 UNICODE 字符可能转化成一个字节或多个字节。

与“ANSI 编码”不同的是:
1. 这些“UNICODE 编码”能够处理所有的 UNICODE 字符。
2. “UNICODE 字符”与“转换出来的字节”之间是可以通过计算得到的。

我们实际上没有必要去深究每一种编码具体把某一个字符编码成了哪几个字节,我们只需要知道“编码”的概念就是把“字符”转化成“字节”就可以了。对于“UNICODE 编码”,由于它们是可以通过计算得到的,因此,在特殊的场合,我们可以去了解某一种“UNICODE 编码算法”是怎样的规则。



参考资料:

1.李晓明等著.搜索引擎——原理、技术与系统.科学出版社.50-59.

2.字符,字节和编码.注:本文所提到的概念和此链接内提到的略有不同。


0 0