1、起源
计算机起源于美国,当时所需要用到的字符比较单一,基本是英文字符和数字及其他一些符号。计算机的数据存储及运算时都是使用二进制表示,而具体哪些二进制数字表示哪个字符,为了通用在计算机中表示这些字符,美国国家标准学会制定一个通用字符编码标准—ASCII码。
2、发展
由于ASCII码只能最多表示128个字符(包括不可见字符),显然不满足全球这么多字符表示(我国汉字就有7万多),又提出使用将字符中最高闲置位也利用起来(之前这个最高字符用于奇偶验证),扩充为256字符
2.1:此时每个国家对256字符进行编码不一样,所表示的字符都不一样,如130在法语到e,而在希伯来语代表gimel。但不管如何前127符号都是一样,不同只有后128符号
2.2:汉语表示的字符串如果只用一个字节来表示,无法满足7万多的汉字的表示。所以采用双字节编码来表示(DBCS:double bytes codesets),理论上256*256=65535
3、Unicode出现
每个国家都制定自己的编码标准,如GB2312(简体汉字),GBK(兼容2312,包含繁体中文BIG5),GB18030(兼容2312,gbk,包含其他少数民族文字等),这样需要先知道每个文本的编码才能进行解码显示正常字符,否则就是一堆乱码。那么能不能有一个统一的编码将全世界的所有字符都纳入,这时Unicode就登场了,可以表示百万级别的字符(可以表示emoji表情)。具体字符:https://home.unicode.org/,汉字:http://www.chi2ko.com/tool/CJK.htm
4、Unicode的问题
Unicode 只是规定了二进制的代码,却没有规定应该如何存储这些二进制,这就导致了下面几个问题
4.1:没有定义该字符是使用一个字节表示还是二个字节表示或者更多字节,比如“基”字的Unicode对应二进制是57FA(至少两个字节),emoji笑脸表情1F607(至少三个字节),没有相应的存储编码(解码)方式,计算机则无法识别
4.2:如果规定了统一数量的字节来字符表示,也会带来极大的浪费,特别是一些拉丁文,大部分用一个字节就可以表示了。
5、UTF的出现
以上问题造成了多种存储方式,导致了Unicode在很长一段时间无法推广。直到互联网广泛应用直接推动了UTF-8出现,这一种是可变大小编码方式,除此之外也用UTF-16(2个字节或者4个字节),UTF-32(4个字节)
6、UTF-8与Unicode的转换关系
Unicode二进制代码:占用大小:UTF-8二进制表示
0000 0000 - 0000 007F : 一字节:0xxx xxxx
0000 0080 - 0000 07FF : 二字节:110x xxxx 10xx xxxx
0000 0800 - 0000 FFFF : 三字节:1110 xxxx 10xx xxxx 10xx xxxx
0001 0000 - 0010 FFFF : 四字节:1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
举例:“基”字(57FA),Unicode二进制表示 0101 0111 1111 1010,57FA在0000 0800 - 0000 FFFF之间,则知道应该用三个字节来表示该字符
那么采用1110 xxxx 10xx xxxx 10xx xxxx,下一步把x替换成Unicode 二进制,从右到左替换
1110 xxxx 10xx xxxx 10xx xxxx
+ 0101 01 1111 11 1010
-------------------------------
1110 0101 1001 1111 1011 1010
因此为:11100101 10011111 10111010,即E5 9F BA
可以通过命令行:echo ‘基' | xxd ,或者echo ‘基' | xxd -b 看到二进制
7、尝试一下
将严(unicode:4E25)字转换成UTF-8
结果:E4B8A5