字符集與編碼(一)——charset vs encoding

注:因爲兩邊同步的麻煩,更多更改及調整可參考個人網站:xiaogd.net 上的字符集編碼與亂碼系列,已將字符集編碼系列與亂碼探源系列合併,更新及勘誤等再也不更新到這邊。html

許多時候,字符集與編碼這兩個概念常被混爲一談,但二者是有差異的,做爲深刻理解的第一步,首先要明確:網站

字符集字符集編碼是兩個不一樣層面的概念

  • charset是character set的簡寫,即字符集ui

  • encoding是charset encoding的簡寫,即字符集編碼,簡稱編碼編碼

與接口及接口實現的對比

能夠把這二者與接口接口實現作個對比:spa

從這裏能夠很清楚地看到,.net

  1. 編碼是依賴於字符集的,就像代碼中的接口實現依賴於接口同樣;code

  2. 一個字符集能夠有多個編碼實現,就像一個接口能夠有多個實現類同樣。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早期與如今的對比

讓咱們來看一個圖,它展示了Unicode早期與如今的一些差異:

注:因爲歷史方面的緣由,你還會在很多地方看到把Unicode和UTF-8混在一塊的狀況,這種狀況下的Unicode一般就是UTF-16或者是更早的UCS-2編碼,在後面的篇章中咱們會進一步分析。

下面是「記事本程序」保存時的一個截圖,是Unicode的一個不規範使用,這裏的Unicode就是指UTF-16:

image

咱們如今說了很多Unicode,因爲各類緣由,必須認可,在不一樣的語境下,「Unicode」這個詞有着不一樣的含義,它可能指:

  • Unicode標準

  • Unicode字符集

  • Unicode的抽象編碼(編號),也即碼點(code point)

  • Unicode的一個具體編碼實現,一般即爲變長的UTF-16(16或32位),又或者是更早期的定長16位的UCS-2

關於這些話題在後面的篇章裏會作進一步探討。

相關文章
相關標籤/搜索