字符编码

字符的机器表示问题

计算机储存数据的方式是以字节为单位的二进制串,如何用计算机来表示现实世界中的字符,也即将二进制串跟字符对应起来。这里用来对应二者的机制就是编码/解码方案(或者叫做编码格式)。编码:将字符表示为二进制串,解码:将二进制串解析为字符。被映射的字符组成的集合叫做字符集,也就是说编码方案和字符集是对应的。被编码的字符如何在系统上显示(即字形),是独立于编码方案外的另外一个问题。

构建二进制串跟字符的一一映射关系,要考虑一些基本问题:

  1. 要用几个字节来作为字符的基本存储单元
  2. 用来存储字符所用的字节数目跟字符集大小(即编码方案可以映射的字符数目)是正相关的
  3. 怎样用尽量少的空间映射尽量常用且尽量多的字符,是设计编码方案时要考虑的重要问题
  4. 按照用来表示字符所用字节数目是否固定,可以将编码方案分为:固定字节编码和变长字节编码
  5. 固定字节编码方案的优点在于简单易解码,对小字符集编码有极大的优势,如用来编码英语字符的ASCII编码方案。固定字节在编码大型字符集时,由于不区分常用和不常用字符都使用同样大小空间编码,造成大量的空间浪费
  6. 变长字节编码方案的优点在于用较少字节表示常用字符,用较多字节表示不常用字符,以尽量用少的空间映射较多的字符,但变长字节编码需要解决字符定界的问题,在解码字节序列时能够正确的判断后续字节是否属于同一字符
  7. 多字节编码字符需要考虑字符的编码值如何存储,这多个字节的编码值应该从低位开始计算还是从高位开始计算
  8. 设计映射方案时,打算映射哪些字符
  9. 我们知道ASCII使用7比特位来表示英语中常用字符,那有没有一种编码方案可以编码全世界所有的字符呢
  10. 显然能够映射的字符越多,则该编码方案越通用,但同时意味着使用更多的储存空间,现实的编码方案是如何解决这个问题的

ASCII 编码

该编码方案主要面向英语字母和数字字符,控制字符以及少量图形字符共128个字符(使用7比特位来编码)。因其可表示的字符数量太少,为了包含欧洲字符,产生了EASII编码方案,该方案使用一个字节进行编码,字符集囊括了部分常用的欧洲字符

GB2312 编码

针对汉字的计算机表示设计了特定的编码方案,大概思路是:如果一个字节小于128,则当成ASCII处理;字节大于128时,跟后续一个字节连在一起表示一个字符,双字节表示的字符包含有常见简体汉字,日文假名,英文字母以及数字。

根据上面提到的编码方案,英文字母、数字以及标点符号都对应了两个编码值,一个是单字节的ASCII编码值,一个是双字节编码值,也即我们常常听到的半角字符,全角字符。

该编码方案囊括了6763个汉字,覆盖了绝大多数常用汉字,但并没有为罕见汉字编码。gb2312编码方案只使用了两字节码位的一部分,微软提出的GBK编码方案对gb2312进行了扩展,可以表示更多的汉字

gb18030最新的国家编码标准,该编码方案采用多字节编码,囊括大概七万多个汉字,繁体汉字,少数民族字符,以及日韩文字

big5是繁体中文常用编码方案

Unicode 字符集

为了编码本国文字,各个国家都制定了自己的编码方案,普通用户不可能在自己系统上同时支持所有方案的编码/解码任务,遇到不支持的编码格式,常常会遇到乱码的情况,这显然不利于数据的交换

unicode字符集囊括了每种语言的每个字符,每个字符都有对应唯一的二进制串,以满足现实世界对跨平台、跨语言数据处理的需求。因此基于unicode编码的系统可以很好的支持多语言环境,推进软件的国际化发展。

当前通用的标准是UCS-2和UCS-4,分别用两字节和四字节来表示字符集,两字节显然显然不足以囊括世界上所有字符,比如:UCS-2只为中、日、韩三种文字共分配了0x3000~0x9fff,但光汉字总字符数就达七万多个,因此UCS-2并不是完全囊括世界上所有字符的编码方案,只是在低存储空间跟大字符集间的折中。

要明白一点,unicode只是用来声明字符到二进制串之间的对应关系,至于二进制串应该如何在计算机储存,如何从二进制串中提取一个字符,则并没有规定,这些标准交给Unicode Transformation Format(即UTF)来定义

UTF 编码

UTF-8, UTF-16, UTF-32都是设计用来表示unicode字符集中全部字符的编码方案。

UTF-8是当前使用最多的编码方案,因为考虑到字符出现频率不同,应该为不同频率的字符使用不同字节长度进行编码,这样可以使得存储空间尽可能的小,UTF-8就是变长编码方案,并且向下兼容ASCII,对ASCII字符依然使用单字节来编码

UTF-8 编码方案:单字节的ASCII字符,字节首位是0;N字节字符,第一个字节的前N位都是1,第N+1位是0,后续字节的前两位是10,其余位置填充为unicode字符的二进制位。

BOM

BOM是放在文件头的若干字节,用来声明该文件的编码格式,常见BOM如下:

EF BB BF    	UTF-8
FE FF     	UTF-16/UCS-2, little endian(UTF-16LE)
FF FE     	UTF-16/UCS-2, big endian(UTF-16BE)
FF FE 00 00  	UTF-32/UCS-4, little endian.
00 00 FE FF  	UTF-32/UCS-4, big-endia
Xiao Wenbin
Xiao Wenbin
Natural Language Processing Engineer

My research interests include machine learning, information retrieval and natural language processing.

Related