gbk编码是什么意思(计算机编码区别)

gbk编码是什么意思(计算机编码区别)

在计算机中,所有的数据在存储和操作的时候都必须用二进制值来表示(因为计算机用高电平和低电平分别表示1和0),以及用哪些二进制数来表示哪些符号,当然大家可以在自己的集合上达成一致(这叫编码),如果大家都想互相交流又不造成混乱,那么大家就必须使用相同的编码规则,这就是统一编码的原因。简单来说,编码就是字符和值的对应关系。下面我们详细介绍不同编码的编码规则和应用。

ASCII 编码

ASCII码是由美国相关标准化组织引入的,后来被国际标准化组织(ISO)指定为国际标准,称为ISO 646标准。标准统一规定了常用字符(a、b、c、d等52个字母(包括大写),0、1等数字,以及一些常用的符号(如:%、!、+等)共52个128 个字符)以二进制数表示。 ASCII分为使用7位二进制数字组合表示128个字符的标准ASCII码和使用扩展ASCII 8位二进制数字组合表示256种字符的ASCII码。

标准 ASCII

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

以下是标准ASCII码表:

扩展 ASCII

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

以下是扩展的ASCII码表:

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

>>> ord('a')

97

ord() 函数本质上返回与字符的 Unicode 代码对应的十进制值。例如

>>> ord("国家")

22269

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

>>> chr(97)

'一种'

>>> chr(22269)

'国家'

GBK

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

由于汉字很多,有些字符还是不能表示,所以重新定义规则:不要求低字节一定是127之后的代码,只要第一个字节大于127,固定表示这是一个中文字符Begin,有或没有扩展字符集内容。这种扩展的编码方案称为GBK,包含了GB2312的全部内容,新增了近20000个汉字(包括繁体字)和符号。但是,中国有56个民族,每个民族都有自己的性格。因此对GBK编码规则进行了扩充,新增了近千个小众字符。扩容后代码为GB18030。 GBK字符包含在GB18030字符中,基本向后兼容GBK。 GB18030共包含汉字70244个。

在 Python 中使用 gbk 和 gb18030 对“汉”字符进行编码:

>>> "汉".encode("gb18030")

b'\xba\xab'

>>> "汉".encode("gbk")

b'\xba\xab'

ANSI:

为了使计算机支持更多的语言,通常使用 0x80~0xFFFF 范围内的 2 个字节来表示 1 个字符。例如:汉字’中’在中文操作系统中存储在两个字节0xD6和0xD0中。然而,不同的国家d地区制定了不同的标准,产生了自己的编码标准如GB2312、GBK、GB18030、Big5、Shift_JIS。 这些使用多个字节来表示字符的各种扩展编码称为 ANSI 编码。在简体中文Windows操作系统中,ANSI编码代表GBK编码在繁体中文Windows操作系统中,ANSI编码代表Big5;而在日文Windows操作系统中,ANSI编码代表Shift_JIS编码。 不同的 ANSI 编码相互不兼容。当信息进行国际交流时,不可能将属于两种语言的文本存储在同一个 ANSI 编码的文本中。 ANSI 编码用一个字节表示英文字符,用两个或四个字节表示中文。

Unicode

因为世界上有很多国家,而且每个国家都定义了自己的一套编码标准,结果无法相互解析和交流,所以ISO(国际标准化组织)决定定义一套编码方案来解决所有国家的编码问题。 ,这种新的编码方案被称为 Unicode。注意Unicode并不是新的编码规则,而是一组字符(每个“字符”都分配了一个唯一的ID(学名是code point/code point/Code Point)),你可以将 Unicode 视为世界编码的字典。可以查询具体符号对应表,也可以查询特殊汉字对应表。

Python中查看一个字符对应的Unicode值的方法:

>>> "中".encode("unicode_escape")

b'\\u4e2d'

>>> b'\\u4e2d'.decode("unicode_escape")

'中间'

需要注意的是,Unicode只是一个符号集,它只规定了符号的二进制代码,而没有规定二进制代码应该如何存储。比如汉字的Unicode是16进制数4E25,转换成15位的二进制数(1001110 00100101),也就是说这个符号的表示至少需要2个字节。对于其他较大的符号,可能需要 3 个字节或 4 个字节,甚至更多。这里有几个严肃的问题。第一个问题是,计算机如何区分 Unicode 和 ASCII?计算机如何知道三个字节代表一个符号,而不是每个字节代表三个符号?第二个问题是我们已经知道英文字母只用一个字节表示。如果Unicode统一规定每个符号用三个或四个字节表示,那么每个英文字母前面必须有两个到三个字节为0,这对于存储或传输都是巨大的浪费,而文本文件的大小将是两个或三倍大,这是不可接受的。它们的结果是Unicode有多种存储方式,这意味着有许多不同的二进制格式可以用来表示Unicode。也导致了 Unicode 在很长一段时间内都无法得到推广,直到 UTF 编码的出现。

UTF-8 编码

由于Unicode是对网络和硬盘资源的浪费,为了解决这个问题,定制了一套编码规则(将“码点”转换为字节序列的规则【编码/解码可以理解为加密/解码】 Unicode 的基础上。解密过程]),这个新的编码规则是 UTF-8。 UTF-8 使用 1-4 个字符来传输和存储数据。它是 Unicode 的变长字符编码,也称为通用码。

Unicode 和 Utf-8 编码规则:使用以下模板相互转换

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

————————————————– ———————-

0000 0000-0000 007F | 0xxxxxxx

0000 0080-0000 07FF | 110xxxxxx 10xxxxxx

0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx

0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Unicode 字符通过在相应模板中添加一个标志位以 Utf-8 编码。例如:“fan”Unicode编码为\u8ff7二进制:10001111 11110111,8ff7在第三个模板范围内,根据模板将10001111 11110111分成三部分1000 111111 110111,然后加上标志位的二进制为: 11101000 10111111 10110111 所以utf-8编码是“E8BFB7”

在 Python 中将 Unicode 字符转换为 UTF-8 编码:

>>>'fan'.encode('utf-8')

b'\xe8\xbf\xb7'

那么如何区分utf-8的每个字符呢? UTF-8根据编码的高位字节来区分每个字符的开头,例如:对于一个字节表示的字符,第一个字节的高位以“0”开头;两个字节表示的字符,第一个的高位t字节以“110”开头,下一个字节以“10”开头;对于三个字节表示的字符,第一个字节以“1110”开头,后两个字节以“10”开头;一个由四个字节表示的字符,第一个字节以“11110”开头,接下来的三个字节以“10”开头。这样,计算机可以识别每个字符由几个字节组成,以便显示正确的信息。

UTF-8 和 Unicode 转换

例如汉字“zhi”,utf-8编码为“\xe6\x99\xba”,对应的二进制为:“11100110 10011001 10111010”,由于一个汉字在utf-8中是3个字节,所以对应的模板是:

0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx

11100110 10011001 10111010 | UTF-8 编码二进制 1110xxxx 10xxxxxx 10xxxxxx |对应模板0110 011001 111010 |去掉模板中的标志位后,01100110 01111010代表十六进制的667A,所以按照规则转换,“zhi”Unicode的编码是667A。

同样,根据Unicode中字符的编码位置,也可以找到对应的utf-8编码。例如:UTF-8编码:\xe8\xbf\xb7,二进制表示为:11101000 10111111 10110111,有3个字节属于第三个模板范围,根据模板去掉标志位后为:1000 111111 110111,结果是单词“fan”的 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)

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编码。例如:“Mi”对应UTF-8编码\xe8\xbf\xb7,则“Hu”的URL编码为%E8%BF%B7。解码方法是去掉%,然后进行UTF-8解码得到实际字符。

计算机以何种编码方式存储和传输数据?

支持Unicode的应用程序(python、VS、VC、谷歌浏览器、记事本等大部分程序都支持(部分程序需要设置编码)。

不支持Unicode的应用程序(如Easy Language等)将存储在控制面板-区域-管理中设置的编码(ANSI)中,例如:简体中文(GBK)、繁体中文(Big5)等。

例如:以国内的编程语言“Easy Language”为例,看看变量在内存中存储的是什么编码

a = "你"

调试输出(取pointer_text(a))

* 1966420

通过CE查看这个内存地址对应的值是0000E3C4,“你”的GBK编码正好是:E3C4。由此可知,Easy Language软件采用GBK编码进行数据存储和传输。

看看数据是如何存储在内存中的:

· 使用 OD 查看

· 与 CE 一起查看

多字符变量“Hello”的GBK字符:c4e3bac3b0a1

OD:

CE(8 字节显示):

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