什么是字符集
相信大家在学习的过程中多多少少都应该看到过或者选择过编码集,而我们基本都是无脑的选择utf-8。 但却不知道背后的意义代表着什么,会对我们程序产生什么影响。
我们知道,所有的数据在内存中都是以二进制形式存储的,数字可以由十进制转化为二进制进行存储,但是字符串符号是如何转化成二进制进行存储的呢,比如字母"a",字符👌,各式各样的颜文字,计算机是如何将他们转化为二进制存储,字符集就为我们提供了一套解决方案,将字符转化为独一无二的编码。
什么是字符编码规则
上面所述的字符集是字符对应的编码的集合,而字符编码规则是指字符如何转化成对应的编码,像ASCII字符集中 字符"a"的编码97,所以说a表示为二进制位0110 0001在计算机存储,那么,a如何转为97?,字符集编码规则就是为了解决这一问题。抽象来说编码规则是字符到编码的映射,字符编码规则是字符集的实现方式。
历史背景
计算机起源于美国,上个世纪,他们对英语字符与二进制位之间的关系做了统一规定,并制定了一套字符编码规则,这套编码规则被称为ASCII编码
ASCII 编码一共定义了128个字符的编码规则,用七位二进制表示 ( 0x00 - 0x7F ), 这些字符组成的集合就叫做 ASCII 字符集
随着计算机的普及,在不同的地区和国家又出现了很多字符编码,比如: 大陆的 GB2312、港台的 BIG5, 日本的 Shift JIS等等
由于字符编码不同,计算机在不同国家之间的交流变得很困难,经常会出现乱码的问题,比如:对于同一个二进制数据,不同的编码会解析出不同的字符 ---摘自Unicode、UTF-8、UTF-16 终于懂了 - 知乎 (zhihu.com)
unicode 的诞生
当互联网迅猛发展,地域限制打破之后,人们迫切的希望有一种统一的规则, 对所有国家和地区的字符进行编码,于是 Unicode 就出现了。
unicode是字符集,它将世界上所有的字符都定义为唯一的编码,这样就可以满足跨语言的文本转化。 unicode字符集的编码范围是0x0000 - 0x10FFFF,能容纳下一百多万个字符。
unicode的编码规则
utf-8
utf-8:utf-8是一种变长的字符编码规则,使用1-4字节表示应该字符,根据字符的不同变换长度,它是被互联网广泛应用最广泛的编码规则,实现了对ASCII码的兼容。它的编码规则为:
- 对于单个字节的字符,第一位设为 0,后面的 7 位对应这个字符的 Unicode 码点。因此,对于英文中的 0 - 127 号字符,与 ASCII 码完全相同。这意味着 ASCII 码那个年代的文档用 UTF-8 编码打开完全没有问题。
- 对于需要使用 N 个字节来表示的字符(N > 1),第一个字节的前 N 位都设为 1,第 N + 1 位设为0,剩余的 N - 1 个字节的前两位都设位 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 编码和解码就简单多了。下面以汉字“汉”为利,具体说明如何进行 UTF-8 编码和解码。
“汉”的 Unicode 码点是 0x6c49(110 1100 0100 1001),通过上面的对照表可以发现,0x0000 6c49 位于第三行的范围,那么得出其格式为 1110xxxx 10xxxxxx 10xxxxxx。接着,从“汉”的二进制数最后一位开始,从后向前依次填充对应格式中的 x,多出的 x 用 0 补上。这样,就得到了“汉”的 UTF-8 编码为 11100110 10110001 10001001,转换成十六进制就是 0xE6 0xB7 0x89。
解码的过程也十分简单:如果一个字节的第一位是 0 ,则说明这个字节对应一个字符;如果一个字节的第一位1,那么连续有多少个 1,就表示该字符占用多少个字节。---摘自彻底弄懂 Unicode 编码 - crazyYong - 博客园 (cnblogs.com)
其余的编码规则
unicode 还有utf-16,utf-32编码规则,有着很大的区别,但殊途同归,都是为了把字符转化为唯一的编码。