1、编码格式
字节
字节(byte),每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,也就是八个进制位一字节。从00000000到11111111。
ASCII编码
ASCII编码规定了128个字符的编码,比如空格“SPACE”是32(二进制00100000),大写的字母A是65(二进制01000001)。由于只占用了一个字节的后面7位,最前面的1位统一规定为0。
非ASCII编码
单字节的字符(8bit位,共256个字符,ascii只用到了7个字节)能表示出来的字符有限。比如无法表示中文。
所以各国各自设计了一种多字节的字符编码来表达自己国家的文字,底层任然是二进制存储,然后通过设计好的编码表将二进制数转换成各种字符。如中国的GBK编码,如全球通用的unicode、utf-8、utf-16等
对于大多数编码,内部都包含了ascii编码,ascii编码为其他编码表的子集。utf-16不包含ascii。非英语国家符合不够用,欧洲国家便利用字节中闲置的最高位编入新的符号。所有这些编码方式中,0—127表示的符号是一样的,不一样的只是128—255的这一段。
亚洲国家如中国,256符合完全不够用,所以必须使用多个字节表达一个符号,如采用两个字节来表示的编码GB2312
世界通用unicode
unicode将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,Unicode当然是一个很大的集合,现在的规模可以容纳100多万个符号。每个符号的编码都不一样。一般采用16进制数直观的查看。只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储
然后有的字符他一个字节就能表示,有的字符他要三个字符。那么计算机如何判断是一个字符还是三个字符,假如都用三个字节,那就是内存的很大浪费。
UTF-8
UTF-8是Unicode的实现方式之一, UTF-8就是在互联网上使用最广的一种unicode的实现方式。其他实现方式还包括UTF-16和UTF-32,不过基本不用。
可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度
编码规则:
1)对于单字节的符号,字节的第一位(字节的最高位)设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
Unicode符号范围(十六进制) | UTF-8编码方式(二进制) |
---|---|
0000 0000-0000 007F | 0xxxxxxx |
0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
a=bytes("王",'utf-8')
p="0x738b" #Unicode王的16进制738b,10进制29579
bin(int("0x738b",16))
Out[126]: '0b111001110001011' #Unicode王的二进制为
a
Out[102]: b'\xe7\x8e\x8b'
[hex(i) for i in a]
Out[130]: ['0xe7', '0x8e', '0x8b']
[bin(i) for i in a]
Out[103]: ['0b11100111', '0b10001110', '0b10001011']
"""
111001110001011 #从右到左填充下面的字节
1110xxxx 10xxxxxx 10xxxxxx
转完后为
11100111 10001110 10001011
"""
m=["0b11100111","0b10001110","0b10001011"]
[hex(int(i,2)) for i in m]
Out[128]: ['0xe7', '0x8e', '0x8b']
2、python常用进制转换
-
整数转字符串
bin(16) #10进制换2进制 Out[66]: '0b10000' oct(16) #10进制转8进制 Out[65]: '0o20' hex(16) #10进制转16 Out[61]: '0x10'
-
字符串转整数
int('0b10000',2) #2进制转10 Out[67]: 16 int('0o20',8) #8进制转10 Out[68]: 16 int('0x10',16) #16进制转10 Out[62]: 16
3、字节串
字节串是一堆二进制的无编码的字节(1Byte),不表示任何东西。一般用来存储以字节为单位的数据
,字节串是不可变的字节序列。字节是0-255之间的整数,字节是数据传输和数据存储的基本单位。
由于1个字节有8bit,所以字节可以使用数字来表示。使用二进制来表示明显过长,一般情况合使用两位数的16进制数表示。
由于十六进制的前128(0x00~0x80)个数与ASCII是一一对应的关系,所以在python中,表示字节串的时候将会出现16进制与ASCII码混合出现的情况
1. Python2的默认编码是ASCII,Python3的默认编码为Unicode。 2. UNICDOE才是真正的字符串,而用ASCII、UTF-8、GBK等字符编码表示的是字节串。 3. 字节串与字符串之间的转换不会改变其中内容。
#python字节串中有16进制有ascii码,统一转换为16进制数
[hex(i) for i in b'\xe6\x88\x91\xe7\x88\xb1\xe5\xad\xa6\xe4\xb9\xa0'] #将字节串中的每2个字节(16个bit)转为16进制显示
Out[80]:
['0xe6',
'0x88',
'0x91',
'0xe7',
'0x88',
'0xb1',
'0xe5',
'0xad',
'0xa6',
'0xe4',
'0xb9',
'0xa0']
# 然后再从走到右进行utf-8转成unicode,
# 借助unicode再呈现字符文本
a=b"\x00\x00\f"
b=['0x00','0x00','0xf']
[bin(int(i,16)) for i in b]
Out[135]: ['0b0', '0b0', '0b1111']
由于整数的在ASCII中,所有只需要一个字节就代表一个数字,但是存在从大往小还是从小往大区别
整数转字节
struct.pack(">I",1024) #一个数字,大端,4个字节
Out[175]: b'\x00\x00\x04\x00'
struct.pack(">II",10,24) #两个数字,大端,4个字节
Out[176]: b'\x00\x00\x00\n\x00\x00\x00\x18'
(1024).to_bytes(4,byteorder="big") #一个数字,大端,4个字节
Out[171]: b'\x00\x00\x04\x00'
字节转整数
a=b'\x00\x00\x00\n\x00\x00\x00\x18'
struct.unpack(">II",a) #使用struct
Out[178]: (10, 24)
int.from_bytes(b'y\xcc\xa6\xbb', byteorder='big') #使用int的from_bytes()方法
s = 'y\xcc\xa6\xbb'
num = int(s.encode('hex'), 16) #借助16进制转换
import array
integerValue = array.array("I", 'y\xcc\xa6\xbb')[0] #使用array包