Unicode 和 UTF-8 之间的关系

174 阅读3分钟

参考:
www.cnblogs.com/tsingke/p/1…
www.zhihu.com/question/23…

字符集(或者称符号集)

为每一个「字符」分配一个唯一的 ID(学名为码位 / 码点 / Code Point)。(需要用编码规则对照着这个字符集来编码,不然没有一个统一的ID根本无法编码解码出同一个意思)

编码规则

将「码位」转换为字节序列的规则(编码/解码 可以理解为 加密/解密 的过程)

ASCII码

我们知道,计算机内部,所有信息最终都是一个二进制值。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字节(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从00000000到11111111。

上个世纪60年代,美国率先制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为 ASCII 码,一直沿用至今。

ASCII 码一共规定了128个字符的码位,比如空格SPACE是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的一位统一规定为0。

ASCII码狭义上其实只代表ASCII码字符集。其实它还包括了ASCII编码。因为ASCII码集比较小,一字节就能全部表示完,所以它的编码规则其实就不言而喻(就是一字节从小到大一一对应)

Unicode

计算机全球化迫切需要一个字符集能够囊括全世界所有的字符,Unicode应运而生。

Unicode 当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,U+4E25表示汉字严。具体的符号对应表,可以查询unicode.org,或者专门的汉字对应表。

由于Unicode的庞大,所以无法用一个字节来去表达出所有字符。这时候就需要一种编码解码规则来实现Unicode。

UTF-8

如上面所说,需要一种编码规则实现Unicode,最笨的办法就是像ASCII编码一样取Unicode能达到的最大值的字节数作为存储基数。但是我们不难发现会存在存储空间浪费的问题(第一个Unicode码可能是很多个0之后1个1,这些0的存储实则上是无用的)。针对这些问题,UTF-8编码规则应运而生。UTF-8是一套以 8 位为一个编码单位的可变长编码。具体的编码方式就参考文头的参考链接吧,里面讲得都很清楚。