1、为什么需要Unicode字符集?
计算机只能识别由0和1表示的二进制,所以用户与计算机进行信息交换时,需要先将字符编码成二进制格式,计算机识别机处理后,再将二进制格式解码还原成字符将信息反馈给用户。
所以信息交换过程中必须约定一套机制:字符与二进制一一映射关系。
美国上世纪60年代建立了英文字符和二进制的编码规范,称之为ASCII编码。ASCII编码采用一个字节,最高位定为0;其余7位用来表示128个字符,包括英文字符、阿拉伯数字、西文字符以及32个控制字符。
由于计算机的发展和普及,世界上各个国家均有相应的字符(仅中文就有近10万个)需要表示(显示),128个字符远远不够!欧洲国家为了解决字符短缺的问题,将ASCII最高位也参与编码,使得可编码的字符个数增加了128个(扩展的ASCII码),但是依然不够使用,导致128~255区间内,各国有各国的编码规则,使得国与国之间信息交换极为不便。
为了
为了彻底解决字符短缺问题,且形成统一的编码规则,Unicode孕育而生。Unicode通过增加编码的字节个数,为世界上所有字符一一映射相应的编码,每个字符都是独一无二,形成了Unicode字符集(不与ASCII冲突)。
2、为什么需要utf-8?
Unicode是一种字符集,囊括了世界上所有字符,理论上讲编码的字节个数没有要求;假设每个字符采用4个字节(可表示2**32个字符)编码,那么仅含有英文字符的文件(ASCII编码就够用了)岂不是存储空间增加3倍?造成极大浪费。而且若采用多字节混合编码(可以是1,2,3等多个字节),这也将带来新的问题:如现有三个字节编码结果,其表示的是一个字符还是两个字符还是三个字符呢?
因此,针对以上两个问题,提出了UTF-8,UTF-8 是实现 Unicode 的方式之一,能够解决存储和解码过程中字符识别问题。
UTF-8 的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
下表总结了编码规则,字母x表示可用编码的位
字节个数 | 编码范围 | 字符个数 | 编码格式 |
---|---|---|---|
1 | U+0000~U+007F | 128 | 0xxxxxxx |
2 | U+0080~U+07FF | 1920 | 110xxxxx 10xxxxxx |
3 | U+0800~U+FFFF | 63488 | 1110xxxx 10xxxxxx 10xxxxxx |
4 | U+10000~U+1FFFFF | 2031616 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
5 | U+200000~U+3FFFFFF | 65011712 | 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
6 | U+4000000~U+7FFFFFFF | 2080374784 | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx |
举例说明UTF-8编码存储过程:
>>>x=\'中\'.encode(\'utf-8\') #将中文字符进行utf-8方式编码>>>for i in x: #查看\'中\'编码后的结果print(bin(i),end=\" \")0b11100100 0b10111000 0b10101101 #这就是\'中\'编码后的二进制
由上可知,“中”的utf-8编码
1110
0100
10
111000
10
101101需要3个字节,按照utf-8规则,去掉格式(红色部分),其值为100111000101101,对应的十六进制即为4e2d,所以’中’字符在Unicode中对应的二进制为U+4e2d。