目录
- 1. Unicode
- 2. UTF-8
- 3. UTF-16
- 4. UTF-32
- 5. 总结
Unicode、UTF-8、UTF-16、UTF-32有什么区别?
这是之前在阿里淘系前端面经上看到的一道题,自己也不是很了解,查阅了相关资料,来整理一下。
1. Unicode
在说
ASCII 码(
- 它是基于拉丁字母的一套电脑编码系统。
- 它定义了一个用于代表常见字符的字典。
- 它包含了"A-Z"(包含大小写),数据"0-9" 以及一些常见的符号。
- 它是专门为英语而设计的,有128个编码,对其他语言无能为力
Unicode的实现的方式:
2. UTF-8
注意:
- 对于单字节的符号,字节的第一位为0,后面的7位为这个字符的
Unicode 编码,因此对于英文字母,它的Unicode 编码和ACSII 编码一样。 - 对于n字节的符号,第一个字节的前n位都是1,第n+1位设为0,后面字节的前两位一律设为10,剩下的没有提及的二进制位,全部为这个符号的
Unicode 码 。
我们来看一下具体的
编码范围(编号对应的十进制数) | 二进制格式 |
---|---|
0x00—0x7F (0-127) | 0xxxxxxx |
0x80—0x7FF (128-2047) | 110xxxxx 10xxxxxx |
0x800—0xFFFF (2048-65535) | 1110xxxx 10xxxxxx 10xxxxxx |
0x10000—0x10FFFF (65536以上) | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
那我们该如何通过具体的
步骤:
- 找到该
Unicode 编码的所在的编号范围,进而找到与之对应的二进制格式 - 将
Unicode 编码转换为二进制数(去掉最高位的0) - 将二进制数从右往左一次填入二进制格式的
X 中,如果有X 未填,就设为0
我们来看一个实际的例子:
“马” 字的
(1)首选确定了该字符在第三个范围内,它的格式是
(2)39532对应的二进制数为
(3)将二进制数填入X中,结果是:
3. UTF-16
1. 平面的概念
在了解
最前面的一个平面称为基本平面,它的码点从0 — 216-1,写成16进制就是
2. UTF-16 概念:
3. UTF-16 编码规则:
- 编号在
U+0000—U+FFFF 的字符(常用字符集),直接用两个字节表示。 - 编号在
U+10000—U+10FFFF 之间的字符,需要用四个字节表示。
4. 编码识别
那么问题来了,当我们遇到两个字节时,我们怎么知道是把它当做一个字符还是和后面的两个字节一起当做一个字符呢?
辅助平面共有 220 个字符位,因此表示这些字符至少需要 20 个二进制位。
因此,当我们遇到两个字节时,发现它的码点在
5. 举例说明
以 “??” 字为例,它的
- 首先计算超出部分的结果:
0x21800 - 0x10000 - 将上面的计算结果转为20位的二进制数,不足20位就在前面补0,结果为:
0001000110 0000000000 - 将得到的两个10位二进制数分别对应到两个区间中
U+D800 对应的二进制数为1101100000000000 , 将0001000110 填充在它的后10 个二进制位,得到1101100001000110 ,转成 16 进制数为0xD846 。同理,低位为0xDC00 ,所以这个字的UTF-16 编码为0xD846 0xDC00
4. UTF-32
比如“马” 字的Unicode编号是:
5. 总结
简单的了解完这几个概念,那就来简单回答一下最开始的那个问题:
Unicode、UTF-8、UTF-16、UTF-32有什么区别?
Unicode 是编码字符集(字符集),而UTF-8 、UTF-16 、UTF-32 是字符集编码(编码规则)UTF-16 使用变长码元序列的编码方式,相较于定长码元序列的UTF-32 算法更复杂,甚至比同样是变长码元序列的UTF-8 也更为复杂,因为其引入了独特的代理对这样的代理机制UTF-8 需要判断每个字节中的开头标志信息,所以如果某个字节在传送过程中出错了,就会导致后面的字节也会解析出错;而UTF-16 不会判断开头标志,即使错也只会错一个字符,所以容错能力教强- 如果字符内容全部英文或英文与其他文字混合,但英文占绝大部分,那么用
UTF-8 就比UTF-16 节省了很多空间;而如果字符内容全部是中文这样类似的字符或者混合字符中中文占绝大多数,那么UTF-16 就占优势了,可以节省很多空间
其实最主要的还是要理解这几个名词的概念,以及编码的步骤和原理。
最后的最后
看了很多篇网上的文章,也查了很多资料,有些地方觉得比较好的就搬过来了,自己也有总结整理。总之,通过写这篇文章的过程,对