注:因爲兩邊同步的麻煩,更多更改及調整可參考個人網站:xiaogd.net 上的字符集編碼與亂碼系列,已將字符集編碼系列與亂碼探源系列合併,更新及勘誤等再也不更新到這邊。html
許多時候,字符集與編碼這兩個概念常被混爲一談,但二者是有差異的,做爲深刻理解的第一步,首先要明確:網站
charset是character set的簡寫,即字符集。ui
encoding是charset encoding的簡寫,即字符集編碼,簡稱編碼。編碼
能夠把這二者與接口及接口實現作個對比:spa
從這裏能夠很清楚地看到,.net
編碼是依賴於字符集的,就像代碼中的接口實現依賴於接口同樣;code
一個字符集能夠有多個編碼實現,就像一個接口能夠有多個實現類同樣。xml
能夠簡單看兩個例子,一個自於html文件,用的是charset:htm
<meta http-equiv="content-type" content="text/html;charset=utf-8">
另外一個來自於xml文件,用的是encoding:接口
<?xml version="1.0" encoding="UTF-8"?>
哪種用法更規範呢?顯然是後者,它更加準確地區分了字符集與編碼的概念。
「charset=utf-8」容易讓人誤解爲存在一種叫「UTF-8」的字符集,但實際上,不管是UTF-8仍是UTF-16,UTF-32都是對同一種字符集的不一樣編碼實現而已。
有不少的字符編碼方案,一個字符集只有惟一一個編碼實現,二者是一一對應的。好比GB2312,這種狀況,不管你怎麼去稱呼它們,好比「GB2312編碼」,「GB2312字符集」,說來講去其實都是一個東西,可能它自己就沒有特地去作什麼區分,因此不管怎麼說都不會錯。
咱們以GB2312爲例,GB=Guo Biao=國標=國家標準,標準出來原本就爲了統一,你一個標準弄出N個編碼實現來,你讓人家用哪一個呢?
事情到了Unicode這裏,變得不同了,惟一的Unicode字符集對應了三種編碼:UTF-8,UTF-16,UTF-32。若是仍是這麼籠統地去稱呼,就很容易搞混了。
人們弄出新的字符集標準,驅動力無外乎是舊的字符集裏的字符不夠用了。
Unicode的目標是統一全部的字符集,囊括全部的字符,因此字符集發展到它這裏就到頭了,再去整什麼新的字符集就不必也不該該了。
但若是以爲它現有的編碼方案不太好呢?在不能弄出新的字符集狀況下,只能在編碼方面作文章了,因而就有了多個實現,這樣一來傳統的一一對應關係就打破了。
咱們嚴格地區分字符集與編碼兩個概念,理由就在這裏。
指定了編碼,它所對應的字符集天然就指定了,編碼纔是咱們最終要關心的。
讓咱們來看一個圖,它展示了Unicode早期與如今的一些差異:
注:因爲歷史方面的緣由,你還會在很多地方看到把Unicode和UTF-8混在一塊的狀況,這種狀況下的Unicode一般就是UTF-16或者是更早的UCS-2編碼,在後面的篇章中咱們會進一步分析。
下面是「記事本程序」保存時的一個截圖,是Unicode的一個不規範使用,這裏的Unicode就是指UTF-16:
咱們如今說了很多Unicode,因爲各類緣由,必須認可,在不一樣的語境下,「Unicode」這個詞有着不一樣的含義,它可能指:
Unicode標準
Unicode字符集
Unicode的抽象編碼(編號),也即碼點(code point)
Unicode的一個具體編碼實現,一般即爲變長的UTF-16(16或32位),又或者是更早期的定長16位的UCS-2
關於這些話題在後面的篇章裏會作進一步探討。