万字长文讲解编码知识,看这文就够了!| 原力计划( 四 )


万字长文讲解编码知识,看这文就够了!| 原力计划

文章插图
这里编码最多也就存在UCS-2(big Endian和LittleEndian先不管,后面会讲) 。
Unicode字符集只规定了码点和文字之间的对应关系,并没有规定码点在计算机中如何存储 。UCS-2和UCS-4就规定了具体的实现,后来改进演变为了UTF-16, UTF-32 。然后又创造了一种全新的简单粗暴好用的变长编码UTF-8,于是乎这三哥们就形成了现代Unicode字符集编码实现的三剑客 。
(3)UTF-16与UTF-32
Unicode与ISO 10646合并统一后,Unicode与 ISO 10646 的通用字符集概念(UCS)相对应 。早期实现Unicode用的编码是UCS-2,后来随着发展发现 216(即65536)个字符不能满足了,Unicode标准本身发生了变化:65536个字符显得不足,引入了更大的31位空间和一个编码(UCS-4),每个字符需要4个字节 。
但是统一码联盟对此予以抵制(这就是为什么我之前说UCS-4是一种理论编码,根本就没付诸实际),这是因为每个字符4个字节浪费了很多磁盘空间和内存,并且因为一些制造商已经在每个字符2个字节的技术上投入了大量资金 。所以最后通过一系列巴拉巴拉讨论规定形成了一种折衷方案,建立了UTF-16编码方案(此时Unicode标准2.0),它替代了原有的UCS-2,并做了改进 。
它与UCS-2一样,它使用两个字节为全世界最常用的63K字符编码,不同的是,它使用4个字节对不常用的字符进行编码 。目的就是为了支持从17个平面编码1,112,064个代码点 。
UTF-16属于变长编码 。我们可以将UTF-16编码看成是UCS-2编码父集 。在没有辅助平面字符(surrogate code points)前,UTF-16与UCS-2所指的是同一意思 。但当引入辅助平面字符后,就称为UTF-16了 。
现在应该认为UCS-2已作废,如果有人还用这种,也不必纠结,它就是表达用定长2字节编码,自己心里清楚就行(基本上你查维基百科上UCS-2都是重定向到UTF-16) 。
另外当时ISO 10646的UCS-4编码并入了Unicode标准,而UCS-4有20多亿个编码空间,但实际使用范围并不超过0x10FFFF,并且为了兼容Unicode标准,ISO也承诺将不会为超出0x10FFFF的UCS-4编码赋值 。
由此提出了实实在在的UTF-32编码(现在也应该认为UCS-4像UCS-2一样作废,维基百科上UCS-4也重定向到UTF-32页面),它的编码值与UCS-4相同,只不过其编码空间被限定在了0~0x10FFFF之间 。因此也可以说:UTF-32是UCS-4的一个子集 。
(现在若有软件声称自己支持UCS-2,那其实是暗指它不能支持在UTF-16中超过2字节的字集 。)
UTF-16(16 位 Unicode转换格式)是一种字符编码,能够对Unicode的所有1,112,064个有效码点进行编码(实际上,此代码点数由UTF-16的设计决定,这个你细品你就知道什么意思,就好像某个班有55个人,根据55个座位确定55个人,而55个座位这个多少是由55个人决定的,两者是相互的,这是一个哲学道理,hh扯远了,所以其中意味自行明白) 。
前面提到过:Unicode编码点分为17个平面(plane),每个平面包含216(即65536)个码位(codepoint),而第一个平面称为“基本多语言平面”(Basic Multilingual Plane,简称BMP),其余平面称为“辅助平面”(Supplementary Planes) 。其中“基本多语言平面”(00xFFFF)中0xD8000xDFFF之间的码位作为保留,未使用 。
UCS-2只能编码“基本多语言平面”中的字符,此时UTF-16与UCS-2的编码一样(都直接使用Unicode的码位作为编码值),例:“汉”在Unicode中的码位为6C49,而在UTF-16编码也为6C49 。
另外,UTF-16还可以利用保留下来的0xD800-0xDFFF区段的码位来对“辅助平面”的字符的码位进行编码,因此UTF-16可以为Unicode中所有的字符编码 。
UTF-16和UTF-32也就是如今Unicode编码的标准之二,他们的区别就是UTF-16是变长编码,大部分是2字节和少部分4字节,UTF-32是定长编码,表示任何字符都用 4 字节
(4)UTF-8
从前述内容可以看出:无论是UCS-2/4还是UTF-16/32,一个字符都需要多个字节来编码,这对那些英语国家来说多浪费带宽啊!(尤其在网速本来就不快的那个年代......),而且我们注意到UTF-16最少2字节和UTF-32不变4字节,这肯定是不兼容ASCII码的,由此,UTF-8产生了 。
在UTF-8编码中,ASCII码中的字符还是ASCII码的值,只需要一个字节表示,其余的字符需要2字节、3字节或4字节来表示 。
UTF-8的编码规则: