天天看点

第31讲 字符串编码转换(和猫妹学Python)

作者:和猫妹学Python

小朋友们好,大朋友们好!

我们今天继续学习字符串,内容如下:

位、字节、字长

编码格式

str和bytes

encode()方法

decode()方法

位、字节、字长

先学习计算机中常用的几个概念,位、字节、字长。

位(bit,缩写为b):代表一个0或1(即二进制)。

字节(Byte,缩写B):每8个位组成一个字节,取值范围00000000~11111111,表示范围0~255。

左侧为高位,右侧为低位。

比如下图表示01000001:

第31讲 字符串编码转换(和猫妹学Python)

不同数量级的换算:

1字节(Byte)=8位(bit)

1KB( Kilobyte,千字节)=1024B

1MB( Megabyte,兆字节)=1024KB

1GB( Gigabyte,吉字节,千兆)=1024MB

1TB( Trillionbyte,万亿字节,太字节)=1024GB

1PB( Petabyte,千万亿字节,拍字节)=1024TB

1EB( Exabyte,百亿亿字节,艾字节)=1024PB

1ZB(Zettabyte,十万亿亿字节,泽字节)=1024EB

1YB( Yottabyte,一亿亿亿字节,尧字节)=1024ZB

1BB( Brontobyte,千亿亿亿字节)=1024YB

字长:CPU一次并行处理的位数称为字长。

手机:32位、64位

计算器:16位、32位、64位

单片机:8位、16位、32位、64位

猫妹的计算机配置,内存16GB,64位操作系统。

第31讲 字符串编码转换(和猫妹学Python)

编码格式

世界上第一台通用计算机:

时间:1946年2月14日

名字:"ENIAC"

诞生地:美国宾夕法尼亚大学诞生。

发明人:是美国人莫克利(JohnW.Mauchly)和艾克特(J.PresperEckert)。

描述:由18000多个电子管组成,体重达30多吨,占地有两三间教室那么大,是一台又大又笨重的机器。

它的诞生具有划时代的意义,对人类历史的发展产生了极其深远的影响。

第31讲 字符串编码转换(和猫妹学Python)

可见计算机最早出现在美国。

美国使用英语,英语26个字符,加上大小写,也不是太多,1个字节(B)可表示256个符号,所以1个字节(B)够使用了,这种编码格式就是ASCII。

ASCII分为标准ASCII 码(基础ASCII码)和扩展ASCII码。

  • 标准ASCII 码:使用前7位表示128个字符。可表示所有的大写和小写字母,数字0 到9、标点符号,以及在美式英语中使用的特殊控制字符 。
  • 扩展ASCII码:后128个称为扩展ASCII码。许多基于x86的系统都支持使用扩展(或“高”)ASCII。扩展ASCII 码允许将每个字符的第8 位用于确定附加的128 个特殊符号字符、外来语字母和图形符号。

标准ASCII,0~31及127(共33个)是控制字符或通信专用字符(其余为可显示字符)。

如控制符:LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(响铃)等;

通信专用字符:SOH(文头)、EOT(文尾)、ACK(确认)等;

ASCII值为8、9、10 和13 分别转换为退格、制表、换行和回车字符。它们并没有特定的图形显示,但会依不同的应用程序,而对文本显示有不同的影响 。

32~126(共95个)是字符(32是空格),其中48~57为0到9十个阿拉伯数字。

65~90为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。

同时还要注意,在标准ASCII中,其最高位(b7)用作奇偶校验位。所谓奇偶校验,是指在代码传送过程中用来检验是否出现错误的一种方法,一般分奇校验和偶校验两种。奇校验规定:正确的代码一个字节中1的个数必须是奇数,若非奇数,则在最高位b7添1;偶校验规定:正确的代码一个字节中1的个数必须是偶数,若非偶数,则在最高位b7添1 。

第31讲 字符串编码转换(和猫妹学Python)

猫妹的测试代码31.1.1.py

# -*- coding: UTF-8 -*-

def testAscii():
  print (u'-----------Ascii 字符测试-----------')
  for i in range(0,256):
  #for i in range(0,256):
    # chr()返回值是当前整数对应的 ASCII 字符
    #print("[",i,"]",chr(i),end=' ')
    print("[",i,"]",chr(i))
 
def main():
  testAscii()
 
if __name__ == "__main__":
    main()
           

中文汉字几千个?

该如何存储呢?

GBK和GB2312是我们指定的中文编码格式标准,使用2个字节表示中文字符。

GB2312编码适用于汉字处理、汉字通信等系统之间的信息交换,通行于中国大陆;新加坡等地也采用此编码。中国大陆几乎所有的中文系统和国际化的软件都支持GB 2312。基本集共收入汉字6763个和非汉字图形字符682个。

GB2312中对所收汉字进行了“分区”处理,每区含有94个汉字/符号。这种表示方式也称为区位码。

01-09区为特殊符号。

16-55区为一级汉字,按拼音排序。

56-87区为二级汉字,按部首/笔画排序。

10-15区及88-94区则未有编码。

举例来说,“啊”字是GB2312之中的第一个汉字,它的区位码就是1601,它的GB2312为(0xA0+0x10,0xA0+0x01=0xB0A1)。区位码=区字节+位字节(与区位码对比:0xB0=0xA0+16,0xA1=0xA0+1)。

GBK向下与GB2312编码兼容,向上支持ISO10646.1国际标准,是前者向后者过渡过程中的一个承上启下的产物。

ASICII、GB2312、GBK、GB18030 之间的关系可以用下图表示

第31讲 字符串编码转换(和猫妹学Python)

随着计算机的发展,各个国家联系越来越多,中国有GBK编码,别的国家有其自身的编码(比如巴基斯坦码、土库曼斯坦码、吉尔吉斯斯坦码、哈萨克斯坦码、乌斯别克斯坦码等),

如果冲突了怎么办?

会产生乱码,比如:

第31讲 字符串编码转换(和猫妹学Python)

要怎么解决各个国家不同编码问题呢?

制订一套统一的标准不就可以了。

Unicode标准的出现就是为了解决各国字符标准不统一的问题,把世界上所有的字符都放在一起,并给它们统一编码。

它的具体实现有UCS-2、UCS-4、UTF-8等。

UCS-2编码,2个字节,可表示65536个字符,后来发现65536太少了。

UCS-4编码,4个字节,可表示2的32次方个字符,将近43亿个字符。并未流行,因为需要存储空间较大。

UTF-8编码,每次传输8位数据,是一种可变长的编码格式。UTF-8编码将UCS-4编码分为4个区间:

第31讲 字符串编码转换(和猫妹学Python)

比如'王'字,UCS-4字符集里面码为:0000 738B,在上述第三区间

'王'字UCS-4位码:111001110001011=0111 001110 001011

UTF-8第三区间: 1110**** 10****** 10******

从后向前插入得到:11100111 10001110 10001011=0xE78E8B

在Python3.x中,默认使用编码格式为UTF-8,这种编码有效格式有效地解决了中文乱码问题。

str和bytes

在Python中,有两种常用的字符串类型,分别是str和bytes。

其中str表示Unicode字符(ASCII或其他),bytes表示二进制数据(包括编码的文本)。

这两种类型的字符串不能拼接在一起。

通常,str在内存以Unicode表示,一个字符对应若干个字节。

在网络上传输或保存磁盘,需要把str转换为字节类型,即bytes类型。

bytes类型的数据是带有b前缀的字符串(单引号或双引号),比如b’\xd2’和b’mr’都是bytes类型的数据。

str类型和bytes类型之间可以通过encode()和decode()方法进行转换,这两个方法是互逆过程。

比如:

str类型的王,对应bytes类型的0xE78E8B。

encode()方法

encode()方法为str对象的方法,可以将字符串转换为二进制(即bytes),也称为编码,格式如下:

strname.encode([encoding=”utf-8”][,errors=”strict”])

  • strname:要进行转换的字符串
  • encoding:可选参数,用于指定进行编码时采用的字符编码,默认为utf-8,如果使用简体中文,可设置为gb2312。当只有这一个参数时,也可以省略前面的”encoding=”,直接写编码。
  • errors=”strict”:可选参数,用于指定错误处理方式,strict指遇到非法字符就抛出异常,ignore指忽略非法字符,replace指用?替换非法字符,xmlcharrefreplace指使用XML的字符引用,默认为strict。

在使用encode()方法时,不会修改原字符串。

猫妹的测试代码31.4.py:

print('-----------1---------------')
str1='A'
strNew1=str1.encode()
print(strNew1)

print('-----------2---------------')
str2='王'
strNew2=str2.encode()
print(strNew2)

strNew2=str2.encode(encoding='gb2312')
print(strNew2)

strNew2=str2.encode('GBK')
print(strNew2)

print('-----------3---------------')
str3='啊'
strNew3=str3.encode(encoding='gb2312')
print(strNew3)
           

decode()方法

decode()方法为bytes对象的方法,用于将二进制数据转换为字符串,也称为解码,格式如下:

bytesname.decode([encoding=”utf-8”][,errors=”strict”])

  • bytesname:要进行转换的二进制数据,通常是encode()方法转换的结果
  • encoding:可选参数,用于指定解码时采用的字符编码,默认为utf-8,如果使用简体中文,可设置为gb2312。当只有这一个参数时,也可以省略前面的”encoding=”,直接写编码。在设置解码采用的字符编码时,需要与编码时采用一致。
  • errors=”strict”:可选参数,用于指定错误处理方式,strict指遇到非法字符就抛出异常,ignore指忽略非法字符,replace指用?替换非法字符,xmlcharrefreplace指使用XML的字符引用,默认为strict。

在使用decode()方法时,不会修改原字符串。

猫妹的测试代码31.5.py

'''
print('-----------1---------------')
str3='好好学习天天向上'
strNew3=str3.encode(encoding='gb2312')
print(strNew3)
'''

byte1=b'\xba\xc3\xba\xc3\xd1\xa7\xcf\xb0\xcc\xec\xcc\xec\xcf\xf2\xc9\xcf'
strNew1=byte1.decode(encoding='gb2312')
print(strNew1)
           

好了,今天的学习就到这里!

我们下次见!

第31讲 字符串编码转换(和猫妹学Python)