文字编码指南

文字编码指南

是否被ASCII,GB2312,GBK,Unicode,UTF-8,UTF-16,UTF-32这些编码搞得“欲仙欲死”?让我们来彻底理解它们!!

“开天”之ASCII

计算机最早通用编码方案是ASCII。采用7位来表示128个字符,它被称为标准ASCII编码。后来还做了扩展,用8位来表示256个字符,叫做ASCII扩展编码。

ASCII

“百花齐放”之ANSI

ANSI美国国家标准协会。每个国家制定自己的编码规则都需要得到ANSI的认可,每个国家或地区的各自编码都可以叫做ANSI编码。我们比较常见的ANSI编码有中国的GB2312,台湾的BIG5。还有一个GBK是微软自己的搞出来的编码,完全兼容GB2312,所以常常可以混淆。

ANSI的标准是什么呢?就是完全兼容ASCII,所以不能占用ASCII的编码范围,其他自己扩展。比如GB2312的编码是从0xA1A10xFEFE,可表示23901个汉字,实际才7000多个,GBK则从0x81400xFEFE,可表示3万多汉字。

不过ANSI有个巨大的缺陷,它不能同时显示不在同一个字符集中的文字,比如不能同时显示阿拉伯文和中文。所以我们需要一个字符集,上面包含了所有国家的字符。

"大一统"之Unicode

基于ASNI的缺陷,Unicode万国码呼之而出。它是一张包含世界上所有文字的编码表。

Unicode的编码范围为0x000000-0x10FFFF,可以容纳1114112个字符。Unicode字符用4个字节来表示,一共有32位,其中最高位为0,接着的7位将Unicode分成了128个Group,再接着的8位将Unicode分成了256个Plane(平面)。而Unicode只使用17个平面,每个平面都有65536个字符,平面的具体划分如下:

平面 编码范围 用途
0 0000-FFFF 基于多文种平面
1 10000-1FFFF 多文种补充平面
2 20000-2FFFF 表意文字补充平面
3 30000-3FFFF 表意文字第三平面
4-13 40000-DFFFF 尚未使用
14 E0000-EFFFF 特殊用途补充平面
15 F0000-FFFFF 保留作为私人使用
16 100000-10FFFF 保留作为私人使用,emoji所在平面

Unicode只是编码表,如何存储到计算机中还需要设计存储方案,我们常见的实现方案有UTF-8,UTF-16,UTF-32。

  • UTF-8
    Unicode编码4个字节太长了,UTF-8对其进行了可变长处理,编码规则如下:
Unicode编码 UTF-8编码模板
000000 - 00007F 0xxx xxxx
000080 - 0007FF 110x xxxx 10xx xxxx
000800 - 00FFFF 1110 xxxx 10xx xxxx 10xx xxxx
010000 - 10FFFF 1110 0xxx 10xx xxxx 10xx xxxx 10xx xxxx

我们来举个例子,“汉”的Unicode码为0x6C49,在0x0800-0xFFFF 之间,使用1110 xxxx 10xx xxxx 10xx xxxx,而0x6C49的二进制数为0110 1100 0100 1001,将这个二进制替换x,则UTF-8最终存到计算机中的编码为1110 0110 1011 0001 1000 1001

  • UTF-16
    UTF-16的编码规则如下(记某一编码为U):
    U<0x10000时,只有两个字节,UTF-16的存到计算机中的编码和Unicode编码值一致。 当U>=0x10000时,u=U-0x10000得到的值最多20位(10FFFF-0x1000=FFFFF),所以将u的二进制填进1101 10xx xxxx xxxx 1101 11xx xxxx xxxx 这个模板,得到最终值,所以有4个字节。我们看到很多两个字节表示的unicode码都是UTF-16,例如\uD842\uDFB7就是UTF-16编码的。

  • UTF-32
    UTF-32很简单,和Unicode编码一一对应,规定为4个字节

emoji 编码问题:
emoji现在十分流行,在IOS5之前,emoji是使用Softbank的编码版本,在IOS5之后,使用了Unicode定义的emoji字符,编码范围为1F600-1F64F。在UTF-8中,其存储为4字节,所以有的时候MySQL在插入emoji符号时会出错,因为MySQL的utf8编码只能插入3字节的,我们只要改MySQL的编码成utf8mb4就好。我们在网页中可以使用UBB编码显示emoji编码。IOS和Android显示emoji是不同的,因为Android没有采用Unicode定义的emoji。

参考文献

  1. 彻底搞懂字符编码(unicode,mbcs,utf-8,utf-16,utf-32,big endian,little endian...)

  2. Emoji与unicode特殊字符的处理


write by jeffwang 2017/2/22

分享