为什么会出现 Unicode?
最开始美国人发明的电脑,它们只有 26
个英文字母,再夹杂着一些其他特殊字符(&
¥
#
等),所有字符加起来也不会超过 256
个字符,所以它们最开始使用 1
个字节(8
个 bit
位,一共可以表示 256
个字符)进行字符的编码(ASCII
码)。
大家要知道,计算机是不认识我们人类输入的任何字符(
a
,b
,c
,d
,赵
,钱
,孙
,李
,검
,색
,하
,다
等),计算机只认识0101
的二进制,所以我们需要有一套字符集,将所有的字符都映射为二进制编码,然后才能存储到计算机中,反过来,从二进制编码也可以得到对应的字符,前提是你必须知道它使用的是哪种字符集。
至于为什么会出现 Unicode
字符集,是因为各国相继都推出了针对自己国家文字的字符集规则,比如中国自己推出的 GBK
、GB2312
等,如果一个文件里边即使用了中文,又使用了韩文、日文,那么我这个文件该如何编码?
所以,基于万物归一的思想,推出了 Unicode
字符集编码。
Unicode 是什么?
Unicode
只是一套字符集,和 ASCII
码字符集一样,是一个映射字符和二进制的关系表。
Unicode 和 UTF-8 是什么关系?
Unicode
本身只规定了每个字符的数字编号是多少,并没有规定这个编号如何存储?
有的人就说了,和 ASCII
一样啊,直接将编号转换成二进制存储就可以了。
是的,这样是可以,这些都是人为来规定的。
编号如何对应到二进制表示呢? Unicode
给出的是类似于插件式的转换方式,可以有多种选择方式,这些插件就是这里说的 UTF-8
、UTF-16
、UTF-32
等。
UTF-32
UTF-32
是最简单的编码,也就是上面所说的直接将编号转换成二进制存储。使用 ·4
· 个字节表示,处理单元为 4
个字节(即一次需要拿到 4
个字节才能解码得到正确的信息)
但是这种方式的编码会带来另外一个问题,大端序/小端序问题,因为它的处理单元是 4
个字节。
UTF-16
UTF-16
使用变长字节,U+0000
到 U+FFFF
的字符(常用字符集),直接用两个字节表示;编号在 U+10000
到 U+10FFFF
之间的字符,需要用四个字节表示。
这种编码方式同样存在大端序/小端序问题。
UTF-8
UTF-8
同样也使用的是变长字节表示,使用的字节个数从 1-4
个字节不等,编号小的使用的字节少,编号大的使用的字节多。
UTF-8
的编码单元是 1
个字节(8 bit
位),所以不需要考虑字节序问题。
PS:编码单元是 1
个字节表示说,1
个字节就能表达某一个具体的含义。
5 个事实
- 计算机中的所有内容都是字节。程序的输入输出都是必须是字节。
- 字节本身是没有含义的,需要我们给字节约定一些含义,大家都遵循这个约定(例如:ASCII 码)
- 世界上的所有文字符号,肯定是超过 256 个的(也就是一个字节能表示的最大长度)
- 字节和Unicode都很重要,你需要处理他们两个之间的关系。
- 不能认为任何东西都是字节或者都是Unicode,你需要明确的转换他们。
- 字节字符串的编码类型,是不能通过测试来确定的。
- 需要通过其他明确的方式来确定。比如说HTTP等协议就包含了编码格式的说明。
- 有时可能会被告知字节字符串的错误的编码格式,所以在解码的时候会导致乱码。
3 个技巧
- 程序内部的字节就不需要处理了(可能是程序自己将Unicode转换成字节的),但是进出程序的数据务必进行处理,进入程序时候将字节decode成Unicode,出程序的时候将Unicode encode成字节。就好比一个三明治。
- 必须知道你即将处理的数据是什么类型的?如果你即将处理的数据类型是字节字符串,你应该知道他是哪种编码类型编码的?
- bebug的时候不应该使用print来查看数据是什么,应该看数据的type是什么?
- 测试对Unicode的支持。
网友评论