一直觉得字符的编码
很玄幻,总是想弄懂,但是一直没有花时间去琢磨,有点😣。所以趁着这段时间空闲,补充补充鸡汤。幸运的是,在谷歌上看到阮一峰大佬的博客,讲的就是关于 Unicode
和UTF-8
以及ASCII
之间的关系,看的我是醍醐灌顶,不愧是大佬,讲的那叫一个透彻~
1、前世ASCII
首先我们的字母都是由8位一个字节的二进制数进行表示的,这样就可以表示256个字符,从 00000000
到11111111
。
后来美国规定了 ASCII
的范围,总共128个字符,占据了后7位,第一位默认就是0。
再到后来,又扩充到256个字符,其实也就是第8位也算进去。但是这里需要注意的是,多的128个符号编码,并不属于 ASCII 码,只能说是扩展的。
之后随着各国语言的增多,就会遇到编码不够的问题,像咱国家的汉字就有很多。所以为了适应这样的需求,Unicode
俗称万国码,就这样诞生了,所有的文字以及字符都对应一个特定 Unicode 编码,实现了编码“大一统”。
2、今生Unicode
包含了各国的文字以及符号,名副其实的万国码。下面是查询 Unicode 的网站:具体的符号对应表,unicode.org,以及查询汉字的汉字对应表。
但是 Unicode 只是定义了字符的编码值,但是并没有定义该怎么存储编码值,其实也就是采取什么样的存储方式表示这个 Unicode 值。大家都知道,一个十进制数字可以采用2进制、8进制、16进制编码,所表示的数在含义上都是一样的。所以就需要一个通用的编码方式来对字符进行编码和解码。
例如:春节的春
字对应的Unicode值为 \u6625
,对应的二进制是1100110 00100101
不足两个字节,那么可以按两个字节进行编码,也可以按照三个以及更多字节,不足的直接补0就好。但是像一个字母只需占用一个字节的就很费,还需要用0补齐两个字节或者更多。那么到底该采取怎样的通用编码方式呢?
那么就请出今天的主角 UTF-8
,互联网上最通用的编码方式之一。值得一提的是,UTF-8 只是 Unicode 的一种实现方式(定义怎么存储 Unicode 的值), Unicode仅仅是定义了字符编号(也就是一个 id 编号)。
3、现在UTF-8
UTF-8
是今天的主角,到目前为止是用的最多的一种编码方式,可能今天是写不完了,写文章真的可以加深自己对于知识的理解。
今天上午继续码字,同时出现了许多类似 UTF-8 的编码方式,如: UTF-8 、UTF-16 、UTF-32 等都是对于 Unicode 存储的一种编码方式 ,至于什么区别吗
- UTF-8:一种可变长度的方案,可使用1~6个字节存储。由此可见存储效率很高
- UTF-16:介于 UTF-8 和 UTF-32 的方案,采用2字节或者4字节进行存储
- UTF32:一种固定的4个字节的存储方式,编码一一对应即可,简单但是存储效率太低。
3.1、UTF-8 编码方式
这个编码方式很重要,一定要手动写写。如果字符占用:
-
占用一个字节,那么最高位是0,其他不变;例如字母A,对应 Unicode 值是 \u65,所以对应 UTF-8 值是
01100101
-
如果占用
n
个字节的字符(判断占用几个字节规则,看下方👇),第一个字节的前n
位用1表示,然后后面再加一个0
。余下的几个字节都是10
开头,将字符对应的 Unicode 的二进制数,从最后面一位填入到UTF-8中的最后一位,由后向前进行填充
。到了前面不足的,补0
即可。
Unicode符号范围 | UTF-8编码方式 (十六进制) | (二进制) ----------------------+--------------------------------------------- 0000 0000-0000 007F | 0xxxxxxx # 1个字节 0000 0080-0000 07FF | 110xxxxx 10xxxxxx # 2个字节 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx # 3个字节 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx # 4个字节
举个例子:
例如:春节的春
字,
字符:春 | 对应值 |
---|---|
Unicode(16进制) | \u6625 |
二进制 | 1100110 00100101 |
UTF-8(16进制) | e6--98--a5 |
UTF-8对应二进制 | 1110 0110---10 011000---10 100101 |
(注:表格中的“--”以及空格是为了观看方便添加的,实际是没有的)
分析过程:首先春
对应的 Unicode 值为 \u6625
(16进制数),然后看上面的对应 Unicode 值的范围,是属于第三行3个字节的编码方式(0000 0800-0000 FFFF
)。
按照对应的编码方式,第一个字节是1110xxxx
,第二个是10xxxxxx
,第三个是10xxxxxx
,然后将 春 对应的 Unicode 值的二进制数,依次从后向前
进行填充,不足的补 0 ,就变成 11100110 10011000 10100101
。
4、编码例子
常见的百度搜索中,搜索中文的时候,会将中文进行UTF-8编码,例如:搜索 春 这个字
https://www.baidu.com/s?wd=%E6%98%A5&ie=utf-8
可以看出,春字对应 UTF-8 编码值确实是 e698a5
总结:
总算是搞懂 ASCII 和 Unicode 以及 UTF-8 之间的关系,在看到编码问题就知道怎么解决了。如果觉得看的不是很懂的话,可以去看看阮一峰大神的文章,链接在下面👇。一些基础的东西还是需要理解并融会贯通的,对于知识和能力的提升都是很有帮助的,所以向着大神冲冲冲~
参考文章:
http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
https://blog.csdn.net/guxiaonuan/article/details/78678043
查询中文 Unicode 网址:http://www.chi2ko.com/tool/CJK.htm
在线编码:https://tool.oschina.net/encode
欢迎评论~