计算机编码原理

码表

理解

计算机保存的是二进制代码,使用码表使每个二进制代码代替十进制数。这张表中规定了字符和二进制的映射关系。计算机存储字符时将字符查询码表,然后存储对应的二进制。计算机取出字符时将二进制查询码表,然后转换成对应的字符显示。

ASCII

美国码表,码表中只有英文大小写字母、数字、美式标点符号等。每个字符占用1个字节,所有字符映射的二进制都为正数,因此有128个字符映射关系。

GBK/GB18030

GBK 编码是使用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBK大。

Unicode

Unicode 是一个很大的集合,是十六进制的,现在的规模可以容纳 100 多万个符号。每个符号的编码都不一样,比如,U+0639表示阿拉伯字母Ain,U+0041表示英语的大写字母A,U+4E25表示汉字“严”。

Unicide 是一个符号集,规定了符号的二进制代码,却没有规定如何存储二进制代码。那么如何区别 unicode 和 ascii 呢?计算机怎么知道三个字节表示一个符号,而不是三个符号?于是就衍生了 UTF-8。

UTF-8

UTF-8 是 unicode 的一种实现方式之一。它是一种可变长度字符集,每个字符编码最多四个字节。

UTF-8的编码规则很简单,只有二条:

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

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

Unicode符号范围 (十六进制) UTF-8编码方式 (二进制)
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

因此对于英语字母,使用 utf-8 与 ascii 是一样的。

UTF-8 存储的字符,除了第一个字节外,其余字节的头两个比特都是以”10”开始,使文字处理器能够较快地找出每个字符的开始位置。

举个栗子

例如“严”,unicode 字符是 4E25(100111000100101)4e25 在第三行范围,因此需要三个字节,将二进制码以此替换掉上面的 x,得到最终的 utf-8 编码为:11100100 10111000 10100101。转换成十六进制就是E4B8A5

虽然 utf-8 具有良好的国际通用性,但是 utf-8 中的中文使用三个字节来编码,比 gbk 多占用了 50% 的存储空间。下面来介绍 gbk 编码方式。

Base64

是基于 64 个可打印的字符来表示二进制的数据的一种方法,用于解决中文、日文等文字无法被服务器或网关有效处理。

64 个字符:A~Z、a~z、0~9、+、/,还会使用 = 做填充字符

转换步骤

  1. 三个字节分一组,每个字节 8 位,总共 24 位
  2. 将 24 位每 6 位分一组,共分为四组(如果不足6位则补0,如果 6 位全是空的,则使用 = 号代替)
  3. 每组前面添加 2 个 0,变为 8 位二进制位,共四个字节
  4. 使用每个字节的值作索引,获得对应的值

参考

一篇文章彻底弄懂Base64编码原理