啥!啥!這寫累都是啥!字符?字符集?字符編碼?ascii?GB2312?UTF8?UTF16?UTF32……

很長一段時間,對於字符集和字符編碼都是處於一種懵懵懂懂的狀態,對於什麼ascii、GB2312、UTF8、UTF16、UTF32、Unicode之類的更是繞的暈暈乎乎,從來沒有正面去徹底搞清楚其中就裏。

今天就在這裏把這些亂七八糟的玩意徹底搞明白。

字符:

什麼是字符?“我”就是一個字符,“你”也是一個字符,“他”也是一個字符。字符就是你在計算機屏幕之上看到的每一個單獨的文字或符號,無關語言,當然,並非每一個字符你都能看到,比如說換行符之類的。

字符集:

顧名思義,字符集就是字符的集合,傳說在很久很久(其實也沒多久啦),有許多的字符集,英文的ascii,中文的GB2312……等等,巴拉巴拉的。

總之,每一種語言都有其相對應的字符集。就醬紫,你品,你細品,我滴乖乖,全世界那麼多種語言,得有多少種字符集纔夠用啊?

當然,人類聰明的大腦自然能夠想到解決之道,那就是Unicode通用字符集。哎呀,這個字符集那可了不得,是所有字符集的大哥大,是國際組織制定的可以容納世界上所有文字和符號的字符編碼方案。目前的Unicode字符分爲17組編排,0x0000 至 0x10FFFF,每組稱爲平面(Plane),而每平面擁有65536個碼位,共1114112個。

我滴乖乖,一百多萬個字符容量,怎麼也夠用了。

綜上,字符、字符集的概念,咱們就簡單的說完了。

但是,字符集與計算機是相互獨立的,因爲計算機只認得00000000000000000100111101100000(Unicode中“你”的二進制編碼),它既不認識“我”,也不認識“你”,想讓它識別出來“你”“我”“他”,就還需要一種映射關係,將“你”與00000000000000000100111101100000映射起來,這種映射關係,就叫做:

字符編碼:

(注意,字符編碼是立足於指定字符集之上的,比如說文件之中標明UTF-8、UTF-16、UTF-32,使用的全是Unicode字符集)

好了,現在咱們有了映射關係的概念,也有了Unicode通用字符集,但是現在又有了新的問題,我要將“你”進行網絡傳輸,肯定是要傳輸00000000000000000100111101100000這一大串,總共是二進制的32位,有朋友疑惑爲什麼是32位,因爲只有32位才足夠映射所有的Unicode字符,這種編碼方式,就叫做UTF-32,意爲每個傳輸字符佔32位空間。

那麼問題來了,大家應該注意到了,二進制的“你”開頭有一堆0,如果我還要傳一個字母“a”,那麼以UTF-32的編碼方式來傳輸,a 的二進制開頭0更多,就是(“你”)00000000111001001011110110100000(“a”)00000000000000000000000001100001。

這是爲什麼呢?

那是因爲,“你”這個字符在Unicode字符集中的十進制編碼爲20320,那麼在二進制的情況下就是隻需兩個字節就夠了,即:0100111101100000。而字符“a”在Unicode字符集中的十進制字符編碼爲97,而二進制要表示97,只需要一字節Byte,也就是8位就足夠了:01100001。

顯然,前面那一大串0,全沒啥用,都是用來佔位的,都是爲了滿足UTF-32每一個字符都應該佔32位的規範。那麼這顯然是對存儲空間或網絡傳輸效益的極大浪費,因爲我一個字母明明用一個字節就能表示,你非要用四個,這不是浪費是什麼?

所以,在這種情況之下,可變長字符編碼規則,即UTF-8、UTF-16出現了。

UTF-8是指爲了表示一個字符,最小要用到二進制8位,即一個字節,最多理論上是6個字節,而UTF-16是指最小要用到二進制16位,即兩個字節,最多理論上也是6個字節。

那麼這兩者是如何實現可變長的呢?計算機是如何識別用UTF-8、UTF-16編碼的數據是由分別是由幾個字節構成一個字符的呢?

道理很簡單,在UTF-8的編碼情況下,只要一個二進制字節以0開頭,即0XXXXXXX(注意,所有描述中出現的X符號,皆是用來存儲Unicode字符集的二進制字符編碼),那該字節必然是一個單字節字符,所以只要遇到字節開頭0,便以單字節形式進行解碼。因爲ascii字符集全是單字節字符,所以說UTF-8兼容ascii。

如果是多字節字符,則構成情況=頭字節+身字節+身字節……這種形式。上面講了單字節必然是以0開頭,那麼多字節必然是以1開頭的了,可是既然多字節都是以1開頭,那麼如何區分哪個是頭字節?哪個是身字節呢?我們接着往下看。

頭字節:

頭字節描述着該字符總共佔用幾個字節,如頭字節110XXXXX意指該字符總共由2個字節構成,1110XXXX是指字符佔3個字節、11110XXX是指字符佔4個字節……以此類推。如此,眼尖的朋友應該注意到了,如果是頭字節,必然必然是以11開頭

身字節:

那麼既然頭字節以11開頭,身字節用10開頭,便可與其作以區分了,即10XXXXXX。於是乎,UTF-8的多字節字符構成方式就是這樣:(2字節)(頭)110XXXXX (身)10XXXXXX、(三字節)(頭)1110XXXX (身)10XXXXXX (身)10XXXXXX

UTF-16與UTF-8的區別就在於,字符的最小傳輸大小是兩字節,那麼所有在兩字節之內便可表達的字符便不再需要頭字節了。這種編碼方式對於字母來說依舊是不友好的,因爲所有字母皆可用單字節表達,另一個字節仍然是無用狀態,因爲多了個無用字節,所以UTF-16不兼容單字節的ascii碼。雖說如此,UTF-16字符編碼對於漢字來說卻是非常適用,因爲如果去除了頭標誌,許多要在UTF-8編碼規則下佔用3個字節的漢字,在UTF-16編碼規則下只需要佔用2個字節。不過就目前的流行情況來看,使用UTF-8編碼格式是主流。

哎呀,寫到這裏,總算把這些亂七八糟的給捋明白了,以後便不會再被各種字符問題絆腳。以上所述如何謬誤之處,歡迎諸位朋友指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章