07 字符编码の小常识

一直以来都对各种字符编码傻傻分不清楚,被工作中经常出现的 ASCII、Unicode、UTF-8 等各类不同的编码术语折腾得偏头痛,所以查了点资料文档了解下各种编码方式的原理。

编码

众所周知,在计算机内部,所有信息最终都表示为一个二进制值,每个二进制位有 01 两种状态。八个二进制位(bit)组成一个字节(byte),一共可以表示 2^8 = 256 种状态。一个状态对应一种符号,即共有 256 种符号,从 0000000011111111

ASCII 码

ASCII 码是美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。ASCII 码使用一个字节来表示一个字符,一共规定了 128 个字符的编码,这些字符只用一个字节的后 7 位,第一位统一为 0

对于英语 ASCII 编码的 128 个符号足够使用,但对于其他语言来说却不够,所以一些语言将字节中闲置的第一位编入新的符号,充分使用 256 个字符。但这样造成了同一个编码在不同语言编码体系中表示不同,造成混乱。

第二个问题是对于一些亚洲国家的文字,比如中文,256 个符号远远不够,必须使用多个字节表示一个符号。比如简体中文的 GB2312 编码方式,使用两个字节表示一个字符,最多可以表示 256 x 256 = 65536 个符号。

Unicode

由于世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。由此 Unicode 应运而生。

Unicode 是一个统一编码集合,类似于世界语,它将世界上所有符号都赋予了一个第一无二的编码。由于每个字符的编码都是唯一的,这样避免了字符编码混乱的问题。

需要注意的是 Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

UTF-8

UTF-8(8-bit Unicode Transformation Format)是 Unicode 的实现方式之一,同时也是互联网上使用最广的一种 Unicode 的实现方式。它规定了 Unicode 符号的存储方式。UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用 1~4 个字节表示一个符号,根据不同的符号而变化字节长度。

UTF-8 的编码规则有两条:

  1. 对于单字节的符号,字节的第一位设为 0,后面 7 位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。

  2. 对于 n 字节的符号(n > 1),第一个字节的前 n 位都设为 1,第 n + 1 位设为 0,后面字节的前两位一律设为 10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

UTF-8 的解读方式:如果一个字节的第一位是 0,则这个字节单独就是一个字符;如果第一位是 1,则连续有多少个 1,就表示当前字符占用多少个字节。