049_Unicode字符编码

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. 049_Unicode字符编码的UTF-8编码和Unicode码的转换

6.1. 049_Unicode字符编码的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, 就是049_Unicode字符编码的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. 049_Unicode字符编码的UTF-16编码和Unicode码的转换

11.1. 049_Unicode字符编码的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就是049_Unicode字符编码的Unicode码值。

上一篇:数据库工作笔记002---新建mysql数据库的时候_对字符集和排序规则的选择


下一篇:java-字符的编码与乱码(1)