昨天博客訪問(wèn)量超過(guò)20w了,很高興,也希望這些筆記和文章能夠真正幫到更多的人。對(duì)于一個(gè)做技術(shù)的人來(lái)說(shuō),分享真的會(huì)給自己帶來(lái)很多快樂(lè)。不過(guò)說(shuō)來(lái)也很慚愧,最近兩個(gè)月都沒(méi)寫什么新的內(nèi)容,一直忙于畢業(yè)設(shè)計(jì)和論文的事,也沒(méi)學(xué)什么新的東西。不過(guò)想到馬上要畢業(yè)將要踏上新的征程也是特別興奮的。
關(guān)于字符串編碼方面的內(nèi)容很基礎(chǔ),學(xué)了很多次還是記不住,每次要用的時(shí)候又去查找相關(guān)資料,很麻煩,這里做一個(gè)總結(jié)記錄一下,方便自己下一次查閱,也加深一下記憶(可能是擼多了,記憶力越來(lái)越差。。)。
百度百科上對(duì)編碼和解碼的定義如下:編碼是用預(yù)先規(guī)定的方法將文字、數(shù)字或其他對(duì)象轉(zhuǎn)換成數(shù)碼的過(guò)程。解碼是編碼的逆向。
這里我們不妨將人類可以很容易理解的消息作為“明文”,將人類不易懂但是更易于存儲(chǔ)和傳輸?shù)南⒆鳛椤懊芪摹?。那么編碼和解碼的關(guān)系如下:
因?yàn)橛?jì)算機(jī)只能識(shí)別0和1,我們?nèi)祟愐子诶斫獾哪切┓?hào)數(shù)字沒(méi)辦法直接存儲(chǔ)到計(jì)算機(jī)中,必須先將這些符號(hào)按照事先規(guī)定的方式編碼成0/1串才能存儲(chǔ)到計(jì)算機(jī)或者通過(guò)網(wǎng)絡(luò)進(jìn)行傳輸。當(dāng)我們從硬盤或者網(wǎng)絡(luò)中讀取文件時(shí),我們讀取到的內(nèi)容全是0/1串,需要將這些內(nèi)容按照一定的方式解碼成我們易于理解的明文,然后才能查看或進(jìn)行相關(guān)的處理。
編碼有一個(gè)必要條件是編碼的過(guò)程不能丟失任何信息,我們能夠從密文解碼出和原文完全一樣的內(nèi)容。
將明文編碼成密文需要按照一定的編碼方式,編碼方式多種多樣,分別對(duì)應(yīng)于不同的字符集。
上個(gè)世紀(jì)60年代,美國(guó)制定了一套字符編碼,對(duì)英語(yǔ)字符與二進(jìn)制位之間的關(guān)系,做了統(tǒng)一規(guī)定。這被稱為ASCII碼,一直沿用至今。
ASCII碼一共規(guī)定了128個(gè)字符的編碼,比如空格”SPACE”是32(二進(jìn)制00100000),大寫的字母A是65(二進(jìn)制01000001)。這128個(gè)符號(hào)(包括32個(gè)不能打印出來(lái)的控制符號(hào)),只占用了一個(gè)字節(jié)的后面7位,最前面的1位統(tǒng)一規(guī)定為0。
對(duì)于英語(yǔ)來(lái)說(shuō)128個(gè)字符就已經(jīng)夠用了,但是對(duì)于其他語(yǔ)言來(lái)說(shuō)卻不夠。因此針對(duì)不同的語(yǔ)言先后出現(xiàn)了多種編碼方式,例如針對(duì)中文的GB2312和GBK編碼,針對(duì)中文繁體的Big5編碼等等,這些編碼方式都使用多個(gè)字節(jié)表示一個(gè)字符。
隨著越來(lái)越多的編碼方式的出現(xiàn),急需一種能夠包含全世界所有符號(hào)的編碼系統(tǒng)來(lái)消滅亂碼,這種編碼系統(tǒng)就叫做Unicode。Unicode只是一套編碼系統(tǒng),包含所有字符集,卻并不規(guī)定編碼后的二進(jìn)制代碼如何存儲(chǔ)。
UTF-32使用4個(gè)字節(jié)存儲(chǔ)每一個(gè)字符,但是對(duì)于英文字符來(lái)說(shuō),使用ASCII編碼只需1個(gè)字節(jié)即可存儲(chǔ),這極大的浪費(fèi)了存儲(chǔ)空間。
因此出現(xiàn)了一種變長(zhǎng)的編碼方式UTF-8,UTF-8是使用得最廣泛的Unicode編碼實(shí)現(xiàn)方式,使用1-4個(gè)字節(jié)表示一個(gè)字符,根據(jù)不同的字符變化長(zhǎng)度。比如對(duì)于英文字符,1個(gè)字節(jié)就夠了,但是對(duì)于中文,可能需要2-4個(gè)字節(jié)才能存儲(chǔ)。
Base64是網(wǎng)絡(luò)上最常見的用于傳輸8Bit字節(jié)代碼的編碼方式,可用于在HTTP環(huán)境下傳遞較長(zhǎng)的標(biāo)識(shí)信息。采用Base64編碼具有不可讀性,可用作簡(jiǎn)單的加密方式。
以前用Python 2,每次使用中文就會(huì)碰到各種編碼問(wèn)題,但是Python 3使得字符串編碼變得非常簡(jiǎn)單。
我們可以通過(guò)以下代碼查看Python 3的字符串默認(rèn)編碼:
import syssys.getdefaultencoding()
Python 3的默認(rèn)編碼方式是UTF-8。
使用Python解釋器進(jìn)行如下編碼解碼操作,在bytes和str之間轉(zhuǎn)換:
>>> '中'.encode()b'\xe4\xb8\xad'>>> b'\xe4\xb8\xad'.decode('utf-8')'中'
我們?cè)谑褂肞ython以二進(jìn)制的形式寫入文件時(shí),需要先將字符串編碼成字節(jié)串,然后再寫入文件。以二進(jìn)制的形式讀取文件時(shí)也是如此,需要將讀取的字節(jié)串解碼成字符串。
參考文檔:
1. 字符編碼筆記:ASCII,Unicode和UTF-8
2. Python 3的bytes/str之別
3. Python3的編碼問(wèn)題
聯(lián)系客服