自动秒收录

计算机编码ASCII、GBK、Unicode、UTF-8和URL编码的区别


文章编号:2363 / 更新时间:2023-12-08 / 浏览:

在计算机中,所有的数据在存储和运算时都要使用二进制数值表示(因为计算机用高电平和低电平分别表示1和0),而具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,这就是统一编码的原因。简单来说编码就是字符与数值的对应关系。

下面我们详细介绍不同编码的编码规则和应用。

ASCII码是由美国有关的标准化组织出台的,后来它被国际标准化组织(InternationalOrganizationforStandardization,ISO)定为国际标准,称为ISO646标准。该标准统一规定了常用字符(像a、b、c、d这样的52个字母(包括大写)以及0、1等数字还有一些常用的符号(例如:%、!、等)总共128个字符)如何用二进制数来表示。ASCII分为标准ASCII码使用7位二进制数组合来表示128种字符和扩展ASCII的8位二进制数组合来表示256种字符。

0-127所包含的码称为标准ASCII编码,如:空格SPACE是32(二进制00100000),大写的字母a是97(二进制01100001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节(8位)的后7位,最前面的一位统一规定为0。

后128个称为扩展ASCII码。扩展ASCII码允许将每个字符的第8位用于确定附加的128个特殊符号字符、外来语字母和图形符号;

在python中可以使用内置函数ord()查看单个字符的ASCII码,例如:

>>> ord('a')97

ord()函数实质是返回字符的Unicode码对应的十进制数值。例如

>>> ord("国")22269

另外,ord()逆函数chr()查看编码对应的字符,例如:

>>> chr(97)'a'>>> chr(22269)'国'GBK 计算机编码ASCIIGBKUnicode

由于ASCII编码是不支持中文的,但又需要寻求一种编码方式来支持中文。于是,国人就定义了一套编码规则:当字符小于127位时,与ASCII的字符相同,但当两个大于127的字符连接在一起时,就代表一个汉字,第一个字节称为高字节(从0xA1-0xF7),第二个字节为低字节(从0xA1-0xFE),这样大约可以组合7000多个简体汉字。这个规则叫做GB2312。

由于中国汉字很多,有些字还是无法表示,于是重新定义了规则:不在要求低字节一定是127之后的编码,只要第一个字节是大于127,就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。这种扩展之后的编码方案称之为GBK,包含了GB2312的所有内容,同时新增了近20000个新的汉字(包括繁体字)和符号。但是,中国有56个民族,每个民族都有自己的文字,所以,对GBK编码规则进行了扩展,又加了近几千个少数民族的字符,再次扩展后得编码叫做GB18030,GBK字符是被包含在GB18030字符内的,与GBK基本向后兼容。GB18030共收录汉字70,244个.

Python中使用gbk和gb18030编码'韩'字:

>>> "韩".encode("gb18030")b'\\xba\\xab'>>> "韩".encode("gbk")b'\\xba\\xab'ANSI

为使计算机支持更多的语言,通常使用0x80~0xFFFF范围内的2个字节来表示1个字符。比如:汉字'中'在中文操作系统中,使用0xD6、0xD0这两个字节存储。但不同的国家和地区制定了不同的标准,由此产生了GB2312、GBK、GB18030、Big5、Shift_JIS等各自的编码标准。这些使用多个字节来代表一个字符的各种延伸编码方式,被称为ANSI编码。在简体中文Windows操作系统为中,ANSI编码代表GBK编码;在繁体中文Windows操作系统中,ANSI编码代表Big5;而在日文Windows操作系统中,ANSI编码代表Shift_JIS编码。不同ANSI编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段ANSI编码的文本中。ANSI编码表示英文字符时用一个字节,表示中文用两个或四个字节。

因为世界上有很多国家,而每个国家都定义一套自己的编码标准,结果相互之间无法解析编码进行通信,所以ISO(国际标准化组织)决定定义一套编码方案来解决所有国家的编码问题,这个新的编码方案就叫做Unicode。注意Unicode不是一个新的编码规则,而是一套字符集(为每一个「字符」分配一个唯一的ID(学名为码位/码点/CodePoint)),可以将Unicode理解为一本世界编码的字典。具体的符号对应表,可以查询,或者专门的汉字对应表。

在Python中查看字符对应Unicode数值的方法:

由于Unicode比较浪费网络和硬盘资源,因此为了解决这个问题,就在Unicode的基础上,定制了一套编码规则(将「码位」转换为字节序列的规则【编码/解码可以理解为加密/解密的过程】),这个新的编码规则就是UTF-8。UTF-8采用1-4个字符进行传输和存储数据,是一种针对Unicode的可变长度字符编码,又称万国码。

Unicode与Utf-8编码规则:使用下面的模板进行互转

Unicode符号范围(十六进制)|UTF-8编码方式(二进制)

Unicode字符通过对应模板加上标志位就后是Utf-8编。例如:"迷"Unicode的编码为\\\u8ff7用二进制表示为:‭1000111111110111‬,8ff7处于第三个模板范围内,把1000111111110111按模板分成三份1000111111110111,然后加上标志位的二进制为:11101000 10111111 10110111所以utf-8编码是"‭E8BFB7‬"

>>>'迷'.encode('utf-8')b'\\xe8\\xbf\\xb7'

那么如何区分utf-8各个字符的?utf-8区分每个字符的开始是根据编码的高位字节来区分的,比如:用一个字节表示的字符,第一个字节高位以"0"开头;用两个字节表示的字符,第一个字节的高位为以"110"开头,后面一个字节以"10开头";用三个字节表示的字符,第一个字节以"1110"开头,后面两个字节以"10"开头;用四个字节表示的字符,第一个字节以"11110"开头,后面的三个字节以"10"开头。这样计算机就可以认出每个字符由几个字节组成,才能显示出正确的信息。

比如汉字"智",utf-8编码是"\\xe6\\x99\\xba"对应的二进制为:"111001101001100110111010",由于utf-8中一个汉字是3个字节,所以对应的模板为:

111001101001100110111010|UTF-8编码成的二进制1110xxxx10xxxxxx10xxxxxx|对应模版0110011001111010|去除模版中的标志位后0110011001111010代表十六进制667A,因此根据规则转换得出"智"Unicode的编码为667A。

同样,根据Unicode中字符的编码位置,也能找到对应的utf-8编码。例如:UTF-8编码:\\xe8\\xbf\\xb7,用二进制表示为:‭111010001011111110110111‬,有3个字节属于第三个模板范围,按模板去掉标志位后是:1000111111110111,结果就是'迷'字的Unicode字符 8ff7。

>>> b'\\\u8ff7'.decode('unicode_escape')'迷'Unicode与GBK编码的转换

Unicode与GBK是两个完全不同的字符编码方案,其两者没有直接关系。如果要对其进行相

互转换,最直接最高效的方法是查询各自的字符对照表。

Python实现Unicode与GBK转换(将Unicode对应数值:\\\u8ff7转GBK字符方法):

>>> l_u = b'\\\u8ff7'.decode('unicode_escape')>>> l_u.encode('gbk')b'\\xc3\\xd4'UTF-8、Unicode与GBK的关系

Utf-8(utf-16)====编码====Unicode=====编码=====GBK(ANSI)

总结:Unicode字符可以通过编码可以得到UTF-8和GBK,相反UTF-8和GBK也可以通过解码得到Unicode,但GBK和UTF-8之间无法直接转换,只能转换到Unicode后再转到另一编码。其实所谓编码转换是数值与字符的转换。

URL编码就是一个字符ascii码的十六进制。不过稍微有些变动,需要在前面加上"%"。比如"\",它的ascii码是92,92的十六进制是5c,所以"\"的URL编码就是%5c。那么汉字的URL编码呢?很简单,非ASCII字符的编码一般有两种,是以GBK或UTF8进行编码。例如:"迷"对应的UTF-8编码\\xe8\\xbf\\xb7,则"胡"的URL编码是%E8%BF%B7。解码方法是去掉%,之后再进行UTF-8解码,就可以得到实际的字符了。

支持Unicode的应用程序(python、VS、VC、GoogleChrome、notepad等大多数程序都支持(部分程序需要设置编码)。

不支持Unicode的应用程序(易语言等)则会以控制面板—区域—管理中设置的编码(ANSI)进行存储,例如:简体中文(GBK)、繁体中文(Big5)等。

例如:以国产编程语言‘易语言’为例,看一下变量在内存中是以什么编码存储的

a = "你"调试输出 (取指针地址_文本型 (a))* 1966420

通过CE查看此内存地址中对应的值为0000E3C4,而"你"的GBK编码正好为:E3C4。由此得知,易语言软件是以GBK编码进行数据存储和传输的。

再看看数据在内存中如何存储:

多字符变量"你好啊"的GBK字符:c4e3bac3b0a1

由此可以看出,内存的存储编码方式与软件支持的编码方式是一致的(易语言:GBK字符;python:Unicode字符);计算机内存数据存储一般采用大端模式(内存高位对数据低位,内存低位对数据高位)。OD默认是从内存低位到高位显示数据,CE默认是从内存高位到低位显示数据,所以看到的十六进制数值是相反的。存储占用的内存大小,会根据变量的数据类型申请对应大小的内存来存储。


相关标签: ASCII编码URL编码蜘蛛技巧超级蜘蛛查

本文地址:https://www.badfl.com/article/15a4e6e9816e1691bf18.html

上一篇:响应式网站优化设计六个技巧...
下一篇:Web服务器软件之IIS漏洞解析...

发表评论

温馨提示

做上本站友情链接,在您站上点击一次,即可自动收录并自动排在本站第一位!
<a href="https://www.badfl.com/" target="_blank">自动秒收录</a>