1、編碼格式
字節(jié)
字節(jié)(byte),每一個(gè)二進(jìn)制位(bit)有0和1兩種狀態(tài),因此八個(gè)二進(jìn)制位就可以組合出256種狀態(tài),也就是八個(gè)進(jìn)制位一字節(jié)。從00000000到11111111。
ASCII編碼
ASCII編碼規(guī)定了128個(gè)字符的編碼,比如空格“SPACE”是32(二進(jìn)制00100000),大寫的字母A是65(二進(jìn)制01000001)。由于只占用了一個(gè)字節(jié)的后面7位,最前面的1位統(tǒng)一規(guī)定為0。
非ASCII編碼
單字節(jié)的字符(8bit位,共256個(gè)字符,ascii只用到了7個(gè)字節(jié))能表示出來的字符有限。比如無法表示中文。
所以各國各自設(shè)計(jì)了一種多字節(jié)的字符編碼來表達(dá)自己國家的文字,底層任然是二進(jìn)制存儲,然后通過設(shè)計(jì)好的編碼表將二進(jìn)制數(shù)轉(zhuǎn)換成各種字符。如中國的GBK編碼,如全球通用的unicode、utf-8、utf-16等
對于大多數(shù)編碼,內(nèi)部都包含了ascii編碼,ascii編碼為其他編碼表的子集。utf-16不包含ascii。非英語國家符合不夠用,歐洲國家便利用字節(jié)中閑置的最高位編入新的符號。所有這些編碼方式中,0—127表示的符號是一樣的,不一樣的只是128—255的這一段。
亞洲國家如中國,256符合完全不夠用,所以必須使用多個(gè)字節(jié)表達(dá)一個(gè)符號,如采用兩個(gè)字節(jié)來表示的編碼GB2312
世界通用unicode
unicode將世界上所有的符號都納入其中。每一個(gè)符號都給予一個(gè)獨(dú)一無二的編碼,Unicode當(dāng)然是一個(gè)很大的集合,現(xiàn)在的規(guī)模可以容納100多萬個(gè)符號。每個(gè)符號的編碼都不一樣。一般采用16進(jìn)制數(shù)直觀的查看。只是一個(gè)符號集,它只規(guī)定了符號的二進(jìn)制代碼,卻沒有規(guī)定這個(gè)二進(jìn)制代碼應(yīng)該如何存儲
然后有的字符他一個(gè)字節(jié)就能表示,有的字符他要三個(gè)字符。那么計(jì)算機(jī)如何判斷是一個(gè)字符還是三個(gè)字符,假如都用三個(gè)字節(jié),那就是內(nèi)存的很大浪費(fèi)。
UTF-8
UTF-8是Unicode的實(shí)現(xiàn)方式之一, UTF-8就是在互聯(lián)網(wǎng)上使用最廣的一種unicode的實(shí)現(xiàn)方式。其他實(shí)現(xiàn)方式還包括UTF-16和UTF-32,不過基本不用。
可以使用1~4個(gè)字節(jié)表示一個(gè)符號,根據(jù)不同的符號而變化字節(jié)長度
編碼規(guī)則:
1)對于單字節(jié)的符號,字節(jié)的第一位(字節(jié)的最高位)設(shè)為0,后面7位為這個(gè)符號的unicode碼。因此對于英語字母,UTF-8編碼和ASCII碼是相同的
2)對于n字節(jié)的符號(n>1),第一個(gè)字節(jié)的前n位都設(shè)為1,第n+1位設(shè)為0,后面字節(jié)的前兩位一律設(shè)為10。剩下的沒有提及的二進(jìn)制位,全部為這個(gè)符號的unicode碼。
| Unicode符號范圍(十六進(jìn)制) | UTF-8編碼方式(二進(jìn)制) |
|---|---|
| 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進(jìn)制738b,10進(jìn)制29579
bin(int("0x738b",16))
Out[126]: '0b111001110001011' #Unicode王的二進(jìn)制為
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 #從右到左填充下面的字節(jié)
1110xxxx 10xxxxxx 10xxxxxx
轉(zhuǎn)完后為
11100111 10001110 10001011
"""
m=["0b11100111","0b10001110","0b10001011"]
[hex(int(i,2)) for i in m]
Out[128]: ['0xe7', '0x8e', '0x8b']
2、python常用進(jìn)制轉(zhuǎn)換
-
整數(shù)轉(zhuǎn)字符串
bin(16) #10進(jìn)制換2進(jìn)制 Out[66]: '0b10000' oct(16) #10進(jìn)制轉(zhuǎn)8進(jìn)制 Out[65]: '0o20' hex(16) #10進(jìn)制轉(zhuǎn)16 Out[61]: '0x10' -
字符串轉(zhuǎn)整數(shù)
int('0b10000',2) #2進(jìn)制轉(zhuǎn)10 Out[67]: 16 int('0o20',8) #8進(jìn)制轉(zhuǎn)10 Out[68]: 16 int('0x10',16) #16進(jìn)制轉(zhuǎn)10 Out[62]: 16
3、字節(jié)串
字節(jié)串是一堆二進(jìn)制的無編碼的字節(jié)(1Byte),不表示任何東西。一般用來存儲以字節(jié)為單位的數(shù)據(jù)
,字節(jié)串是不可變的字節(jié)序列。字節(jié)是0-255之間的整數(shù),字節(jié)是數(shù)據(jù)傳輸和數(shù)據(jù)存儲的基本單位。
由于1個(gè)字節(jié)有8bit,所以字節(jié)可以使用數(shù)字來表示。使用二進(jìn)制來表示明顯過長,一般情況合使用兩位數(shù)的16進(jìn)制數(shù)表示。
由于十六進(jìn)制的前128(0x00~0x80)個(gè)數(shù)與ASCII是一一對應(yīng)的關(guān)系,所以在python中,表示字節(jié)串的時(shí)候?qū)霈F(xiàn)16進(jìn)制與ASCII碼混合出現(xiàn)的情況
1. Python2的默認(rèn)編碼是ASCII,Python3的默認(rèn)編碼為Unicode。 2. UNICDOE才是真正的字符串,而用ASCII、UTF-8、GBK等字符編碼表示的是字節(jié)串。 3. 字節(jié)串與字符串之間的轉(zhuǎn)換不會改變其中內(nèi)容。
#python字節(jié)串中有16進(jìn)制有ascii碼,統(tǒng)一轉(zhuǎn)換為16進(jìn)制數(shù)
[hex(i) for i in b'\xe6\x88\x91\xe7\x88\xb1\xe5\xad\xa6\xe4\xb9\xa0'] #將字節(jié)串中的每2個(gè)字節(jié)(16個(gè)bit)轉(zhuǎn)為16進(jìn)制顯示
Out[80]:
['0xe6',
'0x88',
'0x91',
'0xe7',
'0x88',
'0xb1',
'0xe5',
'0xad',
'0xa6',
'0xe4',
'0xb9',
'0xa0']
# 然后再從走到右進(jìn)行utf-8轉(zhuǎn)成unicode,
# 借助unicode再呈現(xiàn)字符文本
a=b"\x00\x00\f"
b=['0x00','0x00','0xf']
[bin(int(i,16)) for i in b]
Out[135]: ['0b0', '0b0', '0b1111']
由于整數(shù)的在ASCII中,所有只需要一個(gè)字節(jié)就代表一個(gè)數(shù)字,但是存在從大往小還是從小往大區(qū)別
整數(shù)轉(zhuǎn)字節(jié)
struct.pack(">I",1024) #一個(gè)數(shù)字,大端,4個(gè)字節(jié)
Out[175]: b'\x00\x00\x04\x00'
struct.pack(">II",10,24) #兩個(gè)數(shù)字,大端,4個(gè)字節(jié)
Out[176]: b'\x00\x00\x00\n\x00\x00\x00\x18'
(1024).to_bytes(4,byteorder="big") #一個(gè)數(shù)字,大端,4個(gè)字節(jié)
Out[171]: b'\x00\x00\x04\x00'
字節(jié)轉(zhuǎn)整數(shù)
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進(jìn)制轉(zhuǎn)換
import array
integerValue = array.array("I", 'y\xcc\xa6\xbb')[0] #使用array包