1. Unicode字符编码
1.1. Unicode可以被不同的字符集兼容。最常用的编码方式是UTF-8和UTF-16。
1.2. UTF8中的字符可以是1-4个字节长。UTF-8可以表示Unicode标准中的任意字符。UTF-8向后兼容ASCII。UTF-8是网页和电子邮件的首选编码。
1.3. UTF-16: 16比特的Unicode转换格式是一种Unicode可变字符编码, 能够对全部Unicode指令表进行编码。UTF-16主要被用于操作系统和环境中, 比如微软的Windows 2000/XP/2003/Vista/CE以及Java和.NET字节代码环境。
2. Unicode和UTF-8的区别
2.1. Unicode是一个字符集。UTF-8属于编码。
2.2. Unicode是具有唯一十进制数字(代码点)的字符列表。A = 65,B = 66,C = 67,....
2.3. 更简单点理解就是Unicode是数字和字符的一对一的映射。
2.4. 这个十进制数字表示字符串"hello": 104 101 108 108 111。
2.5. 编码指的是如何将这些数字转换成存储在计算机中的二进制数字:
UTF-8编码将像这样存储"hello"(二进制): 01101000 01100101 01101100 01101100 01101111
2.6. 编码将数字转换为二进制。字符集将字符转换为数字。
3. UTF-8编码规则
3.1. 如果一个字节, 最高位(第8位)为0, 表示这是一个ASCII字符(00-7F)。可见, 所有ASCII编码已经是UTF-8了。
3.2. 如果一个字节, 以11开头, 连续的1的个数暗示这个字符的字节数, 例如: 110xxxxx代表它是双字节UTF-8字符的首字节。
3.3. 如果一个字节, 以10开始, 表示它不是首字节, 需要向前查找才能得到当前字符的首字节。
4. 下面是Unicode和UTF-8转换的规则
Unicode字符集 |
UTF-8编码 |
000000~00007F |
0xxxxxxx 0是标记位, x是实际值。 |
000080~0007FF |
110xxxxx 10xxxxxx 110和10是标记位, x是实际值。 |
000800~00FFFF |
1110xxxx 10xxxxxx 10xxxxxx 1110和10是标记位, x是实际值。 |
010000~10FFFF |
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 11110和10是标记位, x是实际值。 |
5. "汉"的UTF-8编码和Unicode码的转换
5.1. "汉"的UTF-8编码是0xE6B189。
5.2. E6转换为二进制1110 0110。
5.3. B1转换为二进制1011 0001。
5.4. 89转换为二进制1000 1001。
5.5. 按照三个字节Unicode和UTF-8转换的规则, 区分标记位和实际值: 1110-0110 10-110001 10-001001。
5.6. 取实际值是: 110110001001001。
5.7. 110110001001001转换为十六进制是0x6C49, 就是"汉"的Unicode码值。
6. 的UTF-8编码和Unicode码的转换
6.1. 的UTF-8编码是0xF0A08081。
6.2. F0转换为二进制1111 0000。
6.3. A0转换为二进制1010 0000。
6.4. 80转换为二进制1000 0000。
6.5. 81转换为二进制1000 0001。
6.6. 按照四个字节Unicode和UTF-8转换的规则, 区分标记位和实际值: 11110-000 10-100000 10-000000 10-000001。
6.7. 取实际值是: 100000000000000001
6.8. 100000000000000001转换为十六进制是0x20001, 就是的Unicode码值。
7. UTF-16编码
7.1. Unicode字符集的取值范围是0x0~0x10FFFF, 超出这个区间UTF-16无法表示。
7.2. 0x0~0xFFFF这段区间, 正好是16位, UTF-16和这个区间的Unicode码, 一一对应。
7.3. 0x10000~0x10FFFF这段区间, 16位存不下, UTF-16使用32位来存储。
7.4. 首先看看0x10000~0x10FFFF这段区间有多少个码位, 0x10FFFF-0x10000+1=0x100000, 这个十六进制数转换为十进制就是: 1048576个码位。
7.5. 32位分开前16位和后16位, 每个16位各存一半, 那么每一半存的就是1024(由来:√1048576=1024, 也就是1024*1024=1048576), 1024代表的是2的10次幂, 也就是10位二进制数。这样就知道了, 32位二进制数字中, 前后16位中各存10位就够用了。
8. UTF-16使用前6位来区分这16位数字代表的位置
8.1. 54开头的为32位的前16位。
8.2. 55开头的为32位的后16位。
8.3. 那么54开头的数据区间是多少呢, 就是1101 10xx xxxx xxxx, 区间就是D800~DBFF。
8.4. 那么55开头的数据区间是多少呢, 就是1101 11xx xxxx xxxx, 区间就是DC00~DFFF。
9. 为了配合UTF-16编码, Unicode字符集也将这两个区间屏蔽掉, 不允许分配任何字符。
10. Unicode码和UTF-16编码转换的规则
10.1. D800转换为二进制1101 1000 0000 0000。
10.2. DC00转换为二进制1101 1100 0000 0000。
10.3. DBFF转换为二进制1101 1011 1111 1111。
10.4. DFFF转换为二进制1101 1111 1111 1111。
10.5. D800区分标记位和实际值: 110110-0000000000。
10.6. DC00区分标记位和实际值: 110111-0000000000。
10.7. DBFF区分标记位和实际值: 110110-1111111111
10.8. DFFF区分标记位和实际值: 110111-1111111111。
10.9. 前16位最小值D800和后16位最小值DC00, 都取实际值是0, 转换为十六进制是0x0。
10.10. 前16位最大值DBFF和后16位最大值DFFF, 都取实际值是11111111111111111111, 转换为十六进制是0xFFFFF。
10.11. 0x0~0xFFFFF + 0x10000 = 0x10000~0x10FFFF。
11. 的UTF-16编码和Unicode码的转换
11.1. 的UTF-16编码是0xD840DC01。
11.2. D8转换为二进制1101 1000。
11.3. 40转换为二进制0100 0000。
11.4. DC转换为二进制1101 1100。
11.5. 01转换为二进制0000 0001。
11.6. 按照Unicode码和UTF-16编码转换的规则, 区分前16位和后16位的标记位和实际值: 110110-00 01000000 110111-00 00000001。
11.7. 取实际值是: 10000000000000001
11.8. 10000000000000001转换为十六进制是0x10001, 再加上0x10000, 0x20001就是的Unicode码值。