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

ASCII

因为计算机的诞生是在美国, 所以一开始只需要存储a, b, c…英文字母和键盘上面的字符和控制字符等. 上个世纪60年代,美国制定了一套字符编码, 对英语字符与二进制位之间的关系, 做了统一规定. 这被称为 ASCII 码, 一直沿用至今.

ASCII 码一共规定了128个字符的编码.如下图所示: 这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的一位统一规定为0。例如: 大写的字母A是65(二进制01000001
「前端基础」字符编码简书
英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。因此要加入更多的字符, 一些欧洲国家使用的编码体系,可以表示最多256个符号。

GB2312, GBK, GB18030

随着后来中国也接触到了计算机, 很明显256个字符来存储汉字明显是不够的, 因此中国国家标准局制定了一套字符编码GB2312(国标2312),但是只收录了6000多汉字, 西文字母和日文假字.这套编码完全兼容ASCII(前0-127是相同的) . 用0000~FFFF表示汉字, 四位的16进制, 也就是2个字节最多可以收录65536个字符.
「前端基础」字符编码简书

然后没有编进去生僻字, 繁体字韩文等. 微软(window在中国和世界其他地区十分流行)在GB2312的基础上推出了GBK(国标扩), 含21886个汉字和图形符号, 收录了中日韩使用的几乎所有汉字, 完全兼容GB2312.
「前端基础」字符编码简书
后面国标局推出了GB18030取代GBK, 但是GB18030不兼容GB2312.

但是后面还存在藏文, 泰文…, 简单, 继续编号就完事了, 这回, 一次性解决全世界的需求.

Unicode(万国码, 统一码)

优点:

  • 已收录13万字符(大于16位), 全世界通用
  • 以后还会继续扩充, 不会停止

缺点:

  • 两个字节不够用, 每个字符要用3个及以上字节.
  • 导致文件体积扩大50%以上, 不划算

UTF-8

这里的关系是,UTF-8 是 Unicode 的实现方式之一。

UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。UTF-8种的8表示最少可用8位存一个字符.

  • UTF-8的鸡贼的存法

存储 「a」
a对应的Unicode编码是97, 十六进制为61.
Unicode直接存: 00000000 00000000 01100001
UTF-8偷懒存法: 01100001

存储 「你」
对应的Unicode编码为4F60
Unicode直接存: 00000000 01001111 01100000
UTF-8偷懒存法:11100100 10111101 10100000

因此UTF-8对英文又存储体积缩小, 对汉字等没有存储体积变化.

  • UTF-8的规则
    「前端基础」字符编码简书
    UTF-8 的编码规则很简单,只有二条:

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

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

「前端基础」字符编码简书
跟据上表,解读 UTF-8 编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。

下面,还是以汉字为例,演示如何实现 UTF-8 编码。
的 Unicode 是4E25100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800 - 0000 FFFF),因此严的 UTF-8 编码需要三个字节,即格式是1110xxxx 10xxxxxx 10xxxxxx。然后,从严的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,严的 UTF-8 编码是11100100 10111000 10100101,转换成十六进制就是E4B8A5

相关文章: