Unicode 是啥?UTF-8 是啥?Unicode 和 UTF-8 有啥不同?
从 C 语言开始,到现在也有十余年了,然而对 Unicode 的理解还是模糊不清,很是惭愧。仔细想想,其实是没分清字符集和字符集编码方案。
什么是字符集?
Unicode 就是一种字符集。
字符,就是我们接触到的数字、字母、标点、文字等图形符号的统称,字符集就是字符的一个集合。除了 Unicode,ASCII 也是常见的一种字符集。大学时,绿皮的《C 语言程序设计》的附录中就有 ASCII 字符集的具体对应图表。比如在 ASCII 码中,65(十进制) 对应的是字符 A,66(十进制) 对应的是字符 B,97(十进制) 对应的是字符 a。一般来说,字符集可以理解为计算机数据到字符图形的映射关系的一个集合。
- ASCII 字符集
ASCII 字符集用用 1 个字节长度的数据来表示 1 个字符,这样一来,该字符集能表示的字符个数,最多不会超过 256 个。实际上,ASCII 字符集中,第 1 个 bit 位统一是 0,所以有 7 个 bit 位可用,也就是可以表示 128 个字符。
对于英文字符,128 个字符基本够用了,但是对于其它语言来说,128 个字符远远不够哦,然后一些欧洲的国家一合计,干脆把 ASCII 码的第 1 个 bit 位也利用上,这样可以表示 256 个字符。也就是扩展 ASCII 码。
- ISO 8859-1字符集
在 ASCII 字符集的基础上又扩充了 128 个西欧常用字符,也可以是使用 1 个字节来进行编码。这个字符集也有一个别名 latin1。
虽然 ASCII 码被扩展了,但是问题也出现了,不同的国家,相同的数字,表示的字符可能不同,比如 144 在阿拉伯人的 ASCII 码中是 گ,而在俄罗斯的 ASCII 码中是 ђ。这就给编码工作(尤其是开发工作者)带来了麻烦。
- gb2312 字符集
2 个字节表示一个字符,也就可以表示 2^16 个字符。这是一个中文的字符集。
- Unicode 字符集
当局面混乱的时候,就需要一个标准来使局面和谐,这个时候,Unicode 诞生了。
Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布(源于百度百科)。
这么说来,Unicode 就是一个超集,他可以表示所有国家的所有字符,那么,如果把这个字符集打印成一本字典,这本字典也一定会很厚。
什么是字符编码方案
提到字符编码方案,就不得不说一下字符在计算机中的存储了。Unicode 字符集中的字符数量超级多,如果所有的字符都用同样长度的数据来表示,显然是空间的浪费。比如字符 1 完全可以用一个字节来表示,偏偏用 4 个自己来存储,实在是没必要。字符集编码方案就起到这样的一个作用,它根据基本的字符集,建立字符和二进制数据的关系,从而根据需要实现字符与数据存储之间的转化。比如,ASCII 码可以表示的字符,依旧用 1 个字节来存储,汉字可能就用 2 个字节来存储,读的时候,将硬盘/内存中的数据转换成对应的字符。
- UTF-8
UTF-8 是一种基于 Unicode 字符集的变长编码方案,它可以使用 1-4 个字节来表示一个数据。它完全兼容 ASCII 字符集。在 UTF-8 方案中,一个汉字一般是用 3 个字节存储,emoji 表情一般用 4 个字节存储。
我们熟悉的 MySQL 中,虽然有 utf8 编码方案,单那不是真正 UTF-8 编码,MySQL 中的 utf8 字符,最多占 3 个字节,所以是没法存储 emoji 表情的。后来推出的 utf8mb4 才支持 4 个字节的字符。
具体的 UTF-8 的实现方式,以后有时间再说。