理解 GBK、Unicode、utf-8

理解 GBK、Unicode、utf-8

首先说明字符集

字符集仅仅是字符的集合,规定了每个字符的码位(也就是它们的位置), 并没有规定具体的编码方式

编码方式

将字符编码成 具体的二进制码,像gbk2312既是字符集又是具体的编码方式;Unicode是字符集,底下的utf-8才是具体的编码方式

网络中传输的都是二进制,这就涉及到字符编码了。

gb2312 编码

​ 1981年5月1日发布的简体中文汉字编码国家标准。收录7445个图形字符,其中包括6763个汉字。GB2312对汉字采用双字节编码。在进行编码之前应先设计字符集,就像ASCII码字符集一样。gb2312使用分区管理方式,一共设计94个分区,每个区94个码位。

  • 01-09区收录682个字符
  • 10-15 为空白区
  • 16-55 收录3755个按拼音排序的汉字

​ 例如:‘饼’ 在 17区的第9行第3列,那么‘饼’的码位就是1793

在这里插入图片描述

有了字符集,那么如何编码呢?

  1. 分别将码位的前两位和后两位转为16进制

    例如: ‘饼’ 的码位 1793 转为16进制后为 0x11 0x5d

  2. 在将结果分别加上0xA0,因为 ASCII 二进制最大为01111111,为了兼容ASCII 最少应该为 0x80 128(1000 0000),但是0x80 - 0x9f 要留给控制块,而0xA0是空格,所以至少要 加上A0,从A1开始

    所以饼的最终16进制为 0xb1 0xfd

所以计算机碰到小于128就知道是ascii码,按一个字节解码,碰到大于0xA0的就知道这是一个汉字然后再向后找一个字节。

gbk编码

对gb2312进行了扩充,共收录21003个汉字。后来又增加了少数民族的文字就有了gb18030

Unicode字符集

为了统一世界上的字符,规定了所有字符的码位

一开始Unicode使用的是 UCS-2字符集,同时也是编码方式,平常说的Unicode编码应该就是这个UCS-2,双字节表示,还是不够用

后来出现了 UCS-4字符集,4字节表示

UTF-8编码

utf-8采用变长的编码方式,采用的是UCS-4字符集。英文占一个字节,中文占3个字节

utf-8将ucs-4的码位划分为了4个区间

编码区间 | 编码样式

0x0000 0000 到 0000 007F | 0xxxxxxx
0x0000 0080 到 0000 07FF | 110xxxxx 10xxxxxx
0x0000 0800 到 0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0x0001 0000 到 0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

这样计算机碰到 0 开头的字节就知道这是一个ASCII字符不会继续向下找,如果碰到 110 开头的字节就知道还有向下找一个字节…

例如:

‘王’的码位为 0x0000 738B, 它在 0x0000 0800 到 0000 FFFF 这个区间内。王的二进制为 00000111 00001110 00001011,然后将其插入到编码样式 ‘1110xxxx 10xxxxxx 10xxxxxx’ 的x中,结果为 11100111 10001110 10001011

看到这就不难理解gbk两字节编码和utf-8两字节编码不一样的原因了(假如都按两字节编码的话)

宽字节注入

采用gbk编码的话,由于计算机碰到第一个字节大于0xA0就会继续向下找一个字节构成一个汉字,如果服务端对输入的单引号进行了转义的话,用户在浏览器输入 %df' 就会变成 %df\',如果数据库采用gbk编码的就会把 %df\ 当成一个汉字,造成sql宽字节注入。

在python爬虫中经常碰到编码不匹配的情况。

requests会从服务器返回的响应头的 Content-Type 去获取字符集编码,如果content-type有charset字段那么requests才能正确识别编码,否则就使用默认的 ISO-8859-1。

例如:

在这里插入图片描述

打印出编码方式

UTF-8
ISO-8859-1

它们的页面分别是这样的

在这里插入图片描述
在这里插入图片描述

所以对不规范的页面要先用 iso-8859-1(单字节编码,兼容ASCII)编码,在按gbk解码

在这里插入图片描述

txt文件打开乱码

如果看懂了前面的话,这个就不难理解了,换一种解码方式打开就行了。同时注意windows的换行 (\r\n) 和linux的换行 (\n) 是不一样的,不注意这个的话有可能导致有些软件读不了txt文件数据,例如 御剑。

后来发现这篇文章写得很好,就是太长了

https://blog.csdn.net/lc11535/article/details/100013653?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-1.searchformbaiduhighlight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-1.searchformbaiduhighlight

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值