字符编解码篇四

阅读条件:

对字符编解码有一些了解,但是又不够深入,在实际项目中遇到问题有些束手无措的同学


<!--more-->

前言

书接上回,我们接着说.前面我们看到随着计算机的迅猛发展,各国家地区为了显示本国的字符,纷纷颁布了自己的字符编码方案.

虽然这解决了本国文字的显示问题.但是不同编码集带来的兼容性问题日益突出.为了解决这种各自为政的问题,统一码联盟颁布了所谓的Unicode, 又称统一码,万国码.

初衷

Unicode的初衷是希望可以包含这个世界上所有的字符,给予统一的编码方式.下面我们根据现代编码模型的结构来逐一分析.

抽象字符表ACR

在这一层包含了世界上已知的绝大多数字符,截止2017年6月支持的字符数量已经超过13w.

编码字符集CCS

Unicode使用整型值为ACR中的字符编号,并将这种编号称为码点(code point).比如中文汉字"中"的码点为U+4E2D. U+表明这是一个Unicode码点,而且使用16进制表示的.4E2D表示具体的码点值.

字符编码表CEF

在CEF层,Unicode就稍显复杂一些了. 为了对码点进行具体的编码,最为直观的方式是将码点直接转为2进制数据.UCS-2UCS-4就是这种思想下的产物.下面我们来具体看看.

UCS-2/UCS-4

UCS是Universal Coded Character Set的缩写.2和4表示的是编码后的大小,分别是2字节和4字节. 通常UCS-2已经可以覆盖我们的使用范围.

还是以中文汉字为例,我们看看对应的UCS-2和UCS-4编码.

UCS-2以两字节编码,直接将码点值转为2进制为\x4e\x2d. UCS-4以四字节编码,将码点值转为2进制后为\x0\x0\x4e\x2d. 我们将这种编码后的序列,称为码元序列.

这种编码方式好处是直观而且便于切割读取,因为编码是固定长度的.但是细心的读者也会发现这种编码方式会极大的浪费存储空间.因为字符的使用频率是不同的.

比如英文字母的使用频率比较高,如果使用UCS-4编码将会浪费3个字节的空间.为了解决这个问题,Unicode又提出了UTF-8编码方案.

UTF-8

UTF-8的目的也是将第二层CCS中的码点进行编码,但是这次我们不会那么直接,我们有一个对应关系.

transfer

还是为中文汉字为例,我们来看看UTF-8编码如何?

首先判断码点的范围,是处于转换方案的第三级.所以采用的公式是1110 xxxx 10xx xxxx 10xx xxxx. code point

plus

通过计算,我们可以得出汉字的UTF-8编码为\xE4\xB8\xAD.

仅以汉字为例,UTF-8的编码长度超过了UCS-2的编码长度.但是仔细观察转换表,会发现英文的UTF-8编码长度一直都是一个字节.这将极大地提高编码效率.

字符编码方案CES

通常我们所说的编码方案都指的是这一层的概念.

对于UCS-2和UCS-4而言,一个码元序列中的顺序是区分不了的.所以我们必须规定大小端的读写顺序. 所以又有了UCS-2-be, UCS-2-le, UCS-4-be, UCS-4-le.

而对于UTF-8而言,一个码元就是一个字节,所以不在需要区分.换言之,UTF-8本身也属于CES层的概念.

总结

至此,我们将Unicode的概念介绍完毕.下面的问题就是操作系统如何使用这些字符编码方案,保存文件,网络传输的时候,如何使用这些编码方案.在编程语言中如何使用这些编码方案.

Ps: 最近做了一个在公司内部做了一个关于字符编解码的分享,反响还不错.下面是PPT链接: 链接: https://pan.baidu.com/s/1eSozK10 密码: j6ap