字符集與編碼理解

字符集的概念其實區別於編碼的概念,而我們有時候卻把他們混淆一談,因爲對於不同的字符集與編碼就是一個東西,說一樣也確實沒有什麼問題,所以導致大家對這兩個概念的混淆。

字符集與字符集編碼是兩個不同層面的東西

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

接口與接口實現的對比

從這裏可以很清楚地看到

1、編碼是依賴於字符集的,就像代碼中的接口實現依賴於接口一樣

(1)字符集就是有序的編號與字符的一一對應,編碼其實就是將這個編號轉換爲計算機的具體存儲方式,具體的計算機存儲的二進制在根據編碼規則就可以反轉回(解碼)字符集代表的編號。

2、一個字符集可以有多個編碼實現,就像一個接口可以有多個實現類一樣。(一個字符集可以對應多種計算機保存編碼的方式或者規則,但是他們都是基於同一個字符集來進行編碼)

3、通過上圖,我們可以看到對於unicode字符集有utf-8、utf-16、utf-32三種編碼,而對於ASCII、GBK他們的字符集即對應編碼,這也就是我們有時候會混淆的原因。

具體例子及規範用法

可以看兩個簡單的例子,一個來自與html文件,用的是charset:

<meta http-equiv="content-type" content="text/html;charset=utf-8">

另一個是來自於xml文件,使用的是encoding:

<?xml version="1.0" encoding="UTF-8"?>

哪一個更加規範呢?通過上面的解釋,相信大家心裏都有一個答案了,那就是使用encoding。encoding表示具體的編碼方式,及文件存儲文字的方式。軟件運行時根據具體的編碼方式進行解碼,轉換爲程序在內存中具體使用的字符集,這樣程序纔會認識我們的字符。(其實我們的字符在內存中也有具體的編碼方式,這就看我們的系統或者軟件允許時使用的字符集編碼了)

“charset=utf-8”容易讓人誤解爲存在一種叫“UTF-8”的字符集,但實際上,無論是 UTF-8,UTF-16 還是 UTF-32 都是對同一種字符集的不同編碼實現而已。

爲什麼要嚴格區分字符集與編碼這兩個概念?

在早期,字符集與編碼是一對一的,但隨着時間的發展,出現了一對多的情形。

字符集與編碼一對一的情形

有很多字符編碼方案,一個字符集只有唯一一個編碼實現,兩者一一對應的。比如GB2312,這種情況,無論你怎麼去稱呼它們,比如“GB2312編碼”,“GB2312字符集”,其實都說的一個東西,可能它本身就沒有特意去做什麼區分,無論怎麼說都不會錯。

字符集與編碼一對多的情形

事情到了 Unicode 這裏,變得不一樣了,唯一的 Unicode 字符集對應了三種編碼:UTF-8,UTF-16,UTF-32。如果還是這麼籠統地去稱呼,就很容易搞混了。

爲什麼Unicode這麼特殊

人們弄出新的字符集,驅動力無外乎就是原來的字符集字符不夠用了,不然誰會閒得蛋疼~~

 

Unicode的目標是統一所有的字符集,囊括所有字符,所以字符發展到它這裏就到頭了,再去整什麼新的字符集就沒必要也不應該了。

但如果覺得它現有的編碼方案不太好呢?在不弄出新的字符集的情況下,那麼就只能在編碼方面上做文章了,於是就有了多個實現,這樣一來,傳統的一一對應關係就打破了。

我們嚴格區分字符集與編碼的概念,理由就在這裏。

指定了編碼,它所對應的字符集自然就指定了,編碼纔是我們最終要關係的。

Unicode的早期與現在的對比

讓我們來看一個圖,它展現了Unicode早期與現在的一些差別:

 

注:由於歷史方面的原因,你還會在不少地方看到把 Unicode 和 UTF-8 混在一塊的情況,這種情況下的 Unicode 通常就是 UTF-16 或者是更早的 UCS-2 編碼

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

我們現在說了不少 Unicode,由於各種原因,必須承認,在不同的語境下,“Unicode”這個詞有着不同的含義,它可能指:

  • Unicode 標準
  • Unicode 字符集
  • Unicode 的抽象編碼(編號),也即碼點(code point)。
  • Unicode 的一個具體編碼實現,通常即爲變長的 UTF-16(16 或 32 位),又或者是更早期的定長 16 位的 UCS-2。

參考自一位大神的文章~~字符集與編碼(一)——charset vs encoding

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