摘要:只有徹底理解編碼,遇到編碼問題才知道問題的根源在哪里,并找到對(duì)應(yīng)的解決辦法?;ㄒ稽c(diǎn)時(shí)間去徹底消化并理解他,長遠(yuǎn)來看,對(duì)以后工作效率的提升是非常值得的。比如中國就制定了等編碼規(guī)范。
只要涉及編程工作,編碼是永遠(yuǎn)繞不開的問題。只有徹底理解編碼,遇到編碼問題才知道問題的根源在哪里,并找到對(duì)應(yīng)的解決辦法。花一點(diǎn)時(shí)間去徹底消化并理解他,長遠(yuǎn)來看,對(duì)以后工作效率的提升是非常值得的。下面是我對(duì)編碼的一些總結(jié)和理解,有不對(duì)之處還望指正。
1. 什么是編碼?為什么會(huì)有編碼(可參考這里)?從根本上來說,計(jì)算機(jī)只能處理0和1,也就是說只能處理由0和1組成的一串串?dāng)?shù)字。讓人直接用01數(shù)字給計(jì)算機(jī)下達(dá)指令或傳輸字符顯然是很困難的;但其實(shí),早期計(jì)算機(jī)剛興起時(shí),那時(shí)的程序員就是寫好01代碼傳給機(jī)器執(zhí)行的。
人用自然語言溝通,而計(jì)算機(jī)只處理01代碼。為了人與計(jì)算機(jī)更友好的交互,有人想了辦法,將自然語言的每個(gè)字符都用一串01數(shù)字串來表示,也就是對(duì)每個(gè)字符用01串來編碼,比如A用0100 0001來表示,這樣就可以制定一個(gè)字符與01數(shù)字串的對(duì)應(yīng)表,也即編碼表,人只需要輸入自然語言(如:Hello),計(jì)算機(jī)通過查編碼表就可以轉(zhuǎn)換為01串,這樣機(jī)器就可以理解并處理了。
2. 為什么會(huì)有多種編碼?眾所周知,世界上第一臺(tái)計(jì)算機(jī)是在美國誕生的,因此,第一種編碼自然是解決英文和01串的對(duì)應(yīng)關(guān)系,這就促生了ASCII編碼的出臺(tái),ASCII編碼表用一個(gè)字節(jié)(8位)包含大小字母、數(shù)字、標(biāo)點(diǎn)符號(hào)以及控制字符。
隨著計(jì)算機(jī)的普及,世界上開始有越來越多的國家使用計(jì)算機(jī),然而,每個(gè)國家都有自己的一套語言,加起來的字符成千上萬。而ASCII最多只能編碼256個(gè)字符,已經(jīng)不能滿足這么多的需求。于是,各國就制定了自己國家的編碼表。比如中國就制定了GB2312、GBK、GB18030等編碼規(guī)范。每個(gè)國家都有自己的一套編碼,這就導(dǎo)致同一串01數(shù)字可能代表兩個(gè)國家不同的字符,或者同一個(gè)字符A,在兩個(gè)國家分別用不同的01數(shù)字串表示。這就導(dǎo)致不同編碼的系統(tǒng)互相傳輸信息時(shí)無法正確識(shí)別,比如中國用GBK編碼的字符傳輸給美國的服務(wù)器,而美國服務(wù)器只有ASCII編碼表,這就很糟糕。
于是,Unicode編碼出現(xiàn)了。Unicode編碼將世界上各個(gè)國家所有的字符全部收錄進(jìn)去,每個(gè)字符都用唯一的01字符串表示,這樣的話就做到了全世界所有字符的統(tǒng)一編碼,各個(gè)國家傳輸信息都用Unicode編碼,根據(jù)Unicode編碼表就可以識(shí)別了。
ASCII:1個(gè)字節(jié),實(shí)際使用7位,第8位保留,表示英文字符
ISO-8859-1:1個(gè)字節(jié),ASCII的升級(jí)版,在ASCII的基礎(chǔ)上添加了歐洲國家的字符,不能表示中文,常用于Java服務(wù)的網(wǎng)絡(luò)傳輸
GB2312:2個(gè)字節(jié),收錄6763個(gè)漢字,只能表示簡體字
GBK:GB2312的升級(jí)版,1個(gè)或2個(gè)字節(jié),收錄21003個(gè)漢字,可以表示簡體字和繁體字
Unicode(即UCS):原始的Unicode是定長的4個(gè)字節(jié),比如字母A,用Unicode表示需要4個(gè)字節(jié),比ASCII多了3個(gè)字節(jié),由于這樣做太浪費(fèi)空間,因此經(jīng)過優(yōu)化制定了變長表示字符的UTF編碼。
UTF-8:用1-6個(gè)字節(jié)表示所有字符,此處使用變長字節(jié)表示,優(yōu)先使用短字節(jié)。
UTF-16:用2、4個(gè)字節(jié)表示所有字符,此處使用變長字節(jié)表示,優(yōu)先使用短字節(jié)。
UTF-32:用4個(gè)字節(jié)表示。
編碼:將字符轉(zhuǎn)為二進(jìn)制(或unicode)。
解碼:將二進(jìn)制(或unicode)轉(zhuǎn)為字符。
首先應(yīng)該知道,內(nèi)存統(tǒng)一用Unicode編碼,編碼轉(zhuǎn)換都統(tǒng)一轉(zhuǎn)到Unicode,再從Unicode轉(zhuǎn)為其他編碼。比如ISO-8859-1和UTF-8之間轉(zhuǎn)換,流程如下:
先知道字符"u"是用ISO-8859-1編碼
獲取字符"u"的二進(jìn)制,java可通過getByte("ISO-8859-1")正確解析出該字符的二進(jìn)制,也可以用十六進(jìn)制表示,比如AF8U
根據(jù)某種規(guī)則,將ISO-8859-1的AF8U轉(zhuǎn)化Unicode,再轉(zhuǎn)化為UTF-8的4E2D
JDK先檢查源文件的編碼類型,如果沒有指定編碼類型則用系統(tǒng)的編碼讀取源文件,如果指定了編碼類型則用指定的編碼類型打開源文件。
打開源文件后,在內(nèi)存中編譯為.class文件,此時(shí),.class文件是Unicode編碼
將內(nèi)存中的.class文件存入硬盤,此時(shí),.class文件仍然是Unicode編碼
看瀏覽器使用的是什么編碼,則顯示的頁面就是使用什么編碼。
發(fā)送post請(qǐng)求時(shí),看瀏覽器用的什么編碼,則發(fā)送過去的數(shù)據(jù)就是用什么編碼
一般可以查看headers里ContentType,charset是什么編碼
服務(wù)器收到請(qǐng)求后,經(jīng)過正確的編碼規(guī)則解析,服務(wù)器才可以正常識(shí)別
服務(wù)器發(fā)送請(qǐng)求時(shí),經(jīng)過正確的編碼規(guī)則編碼,瀏覽器才可以正常顯示。瀏覽器也可以自定義編碼去解析
記?。?/strong> 不管是爬蟲獲取的,瀏覽器收到的還是從本地硬盤讀取的,都是二進(jìn)制,選擇正確的編碼類型,才能把二進(jìn)制或者說01序列解析為正確的字符。也就是用何種方式解析01數(shù)字。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/77886.html