常說的字符集和編碼區(qū)別,其實(shí)就是編碼字符集和字符集編碼的區(qū)別,其實(shí),單單如果只是說字符集,沒有任何編碼的概念的話,那么字符集其實(shí)僅僅是一個(gè)簡(jiǎn)單的字符的集合,或者說是一個(gè)抽象的字符的集合,包括文字,符號(hào)等等,不參與任何存儲(chǔ)形式,只是存在這么各種各樣標(biāo)準(zhǔn)的字符的集合

如果僅僅是抽象的字符集,我們是無需拿出討論的,因?yàn)闆]有任何異議,通俗易懂,而常說的字符集指的編碼字符集,比如常見的 unicode、ascii、gb2312、gbk等,這些我們常稱做為字符集(其實(shí)是編碼字符集),這些字符集,比如unicode其實(shí)本質(zhì)上是已經(jīng)“編碼”過的字符集,即每個(gè)字符都有唯一的整數(shù)編號(hào),每個(gè)字符都有自己特有的編號(hào),同一個(gè)字符在不同編碼字符集中編號(hào)也會(huì)不同,當(dāng)然很多編碼字符集都是ascll的超集,所以ascll字符集的編號(hào)與很多編碼字符集中編號(hào)都一樣,比如英文字母“A”,在ASCII及Unicode及GB2312中,均是第0×41個(gè)字符,說到這里朋友一定注意到了我上面再描述“ unicode其實(shí)本質(zhì)上是已經(jīng)“編碼”過的字符集”中的“編碼”二字加了雙引號(hào),我要強(qiáng)調(diào)的是這里的“編碼”并不是真的我下面要說的編碼,這里只是為每個(gè)字符編了一個(gè)對(duì)應(yīng)的編號(hào),但是我們還是習(xí)慣專業(yè)的稱呼為“編碼字符集”

我們經(jīng)常說“文章采用的是utf-8編碼方式”

我對(duì)于這個(gè)編碼方式的意義,個(gè)人理解是 將一個(gè)字符的整數(shù)編號(hào)用一個(gè)什么二進(jìn)制的整數(shù)值來對(duì)應(yīng)并在計(jì)算機(jī)存儲(chǔ)。這和上面說的編碼字符集中的“編碼”千差萬別,這里我們稱之為“字符集編碼”,即我們常說的編碼

說到這里,很多人會(huì)覺得那么unicode和utf-8的區(qū)別在哪里?既然上文說到unicode是編碼字符集,那么utf-8又是什么?就是常說的編碼?

“文章采用的是utf-8編碼方式”,個(gè)人覺得準(zhǔn)確的說法是“文章采用的是基于unicode編碼字符集的utf-8的編碼方案”,即

即unicode本身作為編碼字符集沒有任何存儲(chǔ)形式,只是一個(gè)編號(hào)和字符對(duì)應(yīng)的表而已,如何在計(jì)算機(jī)存儲(chǔ)?你可能想到了干脆直接把編號(hào)當(dāng)作二進(jìn)制數(shù)值來直接存儲(chǔ),那么為什么不這么做呢?這也算是一種字符集編碼方案,就是基于unicode編碼字符集的utf-32編碼方案,那么有沒有更加智能一點(diǎn)的編碼方案呢?為什么會(huì)沒有呢?那就是utf-8、utf-16等等, 等等,在我解釋為何要用utf-8編碼方案的時(shí)候,我必須說明一件事情:如下

我在上一篇文章《你不知道的 頁(yè)面編碼,瀏覽器選擇編碼,get,post各種亂碼由來》中說過:“如何查看中文字符的十六進(jìn)制字符串?方法:BitConverter.ToString(System.Text.Encoding.UTF8.GetBytes(“阿道夫”));” 請(qǐng)注意我可以改為“System.Text.Encoding.Unicode.GetBytes” 如下圖是vs2013 Encoding鍵入“.”后的智能提示

112227067411272

112226562562235

(列表過長(zhǎng),用兩幅圖分別截圖)

上圖有兩個(gè)疑問:

1、如果說unicode是編碼字符集,為何會(huì)出現(xiàn)在和utf-8這種編碼方案并列的列表中?

2、ASCII或者gb2312都是編碼字符集為何也會(huì)出現(xiàn)在和utf-8這種編碼方案并列的列表中?

我們假設(shè)有兩個(gè)猜測(cè):

1、此處的unicode并不是真正的unicode編碼字符集,可能只是一種和unicode編碼字符集關(guān)系非常緊密的一種編碼方案

2、ASCII或者gb2312(其實(shí)就是圖中的Default,即操作系統(tǒng)當(dāng)前的編碼,國(guó)內(nèi)一般為gb2312)是編碼字符集沒有錯(cuò),但是對(duì)于ASCII或者gb2312都只有唯一一種編碼,那么我稱呼它們?yōu)锳SCII編碼或者GB2312編碼也沒有問題,既然這樣,那我把a(bǔ)scii和gb2312加入和utf-8這種編碼方案并列的列表中也理所當(dāng)然?

我的兩個(gè)假設(shè),很快得到論證

1、在Encoding 的元數(shù)據(jù)看到:

//
        // 摘要:
        //     獲取使用 Little-Endian 字節(jié)順序的 UTF-16 格式的編碼。
        //
        // 返回結(jié)果:
        //     使用 Little-Endian 字節(jié)順序的 UTF-16 格式的編碼。
        public static Encoding Unicode { get; }

這里解釋在這里的unicode其實(shí)本質(zhì)上“獲取使用 Little-Endian 字節(jié)順序的 UTF-16 格式的編碼”,即使基于unicode編碼字符集的utf-16編碼方案,類似的有BigEndianUnicode(獲取使用 Big Endian 字節(jié)順序的 UTF-16 格式的編碼)

2、一般的ASCII或者gb2312,我們可以稱呼為ASCII字符集也可以稱呼為ASCII編碼,只是意義不同而已,因?yàn)閷?duì)于ASCII編碼字符集或者gb2312編碼字符集都只有唯一一種編碼,就是ASCII編碼和GB2312編碼,那么列表中顯示的ASCII和GB2312指的不是編碼字符集而是ASCII和GB2312的編碼方案,我想正是這種原因,才在很多時(shí)候,不管是字符集賦值還是編碼方案賦值都可以直接用gb2312或者ascii,比如:

Encoding gb2312 = Encoding.GetEncoding(“gb2312″);

Response.ContentEncoding = gb2312;//編碼

Response.Charset=”gb2312″;//字符集

總結(jié)下的說:

就是unicode是字符集,不是編碼!但是ascii(gb2312)是字符集,這個(gè)說法肯定正確,但是我表達(dá)為“ascii編碼”也不能說大錯(cuò)特錯(cuò),但是這種說法讓人誤解,如果一定要說那么就說“ascii編碼字符集的編碼”

如果理解上面兩個(gè)假設(shè)的論證道理,那么我們繼續(xù)討論之前暫停的話題,即“解釋為何要用utf-8等編碼方案(其他utf編碼方案類似)”

utf-8將很大一部分基于unicode編碼字符集的字符的整數(shù)編號(hào)作了變換后存儲(chǔ)在計(jì)算機(jī)中。(引用)以“漢”字為例,“漢”的Unicode值為0x6C49,但其編碼為UTF-8格式后的值為0xE6B189(注意到變成了三個(gè)字節(jié))。對(duì)于UTF-16編碼方案,則是對(duì)unicode編碼字符集中的前65536個(gè)字符編號(hào)都不做變換,直接作為計(jì)算機(jī)存儲(chǔ)時(shí)使用的值(對(duì)65536以后的字符,仍然要做變換),例如“漢”字的Unicode編號(hào)為0x6C49,那么經(jīng)過UTF-16編碼后存儲(chǔ)在計(jì)算機(jī)上時(shí),它的表示仍為0x6C49,對(duì)于UTF-32編碼方案,他對(duì)所有的Unicode字符均不做變換,直接使用編號(hào)存儲(chǔ),只是這種編碼方案太浪費(fèi)存儲(chǔ)空間(就連1個(gè)字節(jié)就可以搞定的英文字符,它都必須使用4個(gè)字節(jié))

既然unicode編碼字符集有如此多的編碼方案,那么

utf-8,字母數(shù)字符號(hào)等占1字節(jié),漢字占三字節(jié)

utf-16,對(duì)unicode編碼字符集中的前65536個(gè)字符都占兩個(gè)字節(jié)

utf-32,全部占四字節(jié)

如果還有人問:

“unicode編碼每個(gè)字符占幾個(gè)字節(jié)”,我們可以理直氣壯的說,第一unicode不是編碼!第二每個(gè)字符具體占多少字節(jié)是要看編碼方案!

很多面試題會(huì)問:

string param = "abc阿道夫";
int length1 = System.Text.Encoding.Unicode.GetBytes(param).Length;//別忘了這里的unicode本質(zhì)是utf-16編碼方案
int length2 = param.Length;

那么答案就是12和6了

最后,對(duì)于gb2312或者ascii編碼字符集的字符的編號(hào)就是直接存儲(chǔ)在計(jì)算機(jī)中的二進(jìn)制數(shù),也就是說gb2312和ascii編碼字符集都只有一種編碼方案,因?yàn)樵趃b2312編碼字符集中的ascii字符集部分的編號(hào)并沒有變化(即和ascii編碼字符集中的編碼一致),所以gb2312的ascii部分字符存入計(jì)算機(jī)的二進(jìn)制數(shù)還是占用1個(gè)字節(jié),而中文字符存入計(jì)算機(jī)的二進(jìn)制數(shù)也是該中文字符在gb2312編碼字符集中的編號(hào),該編號(hào)一般轉(zhuǎn)換成二進(jìn)制數(shù)都占兩個(gè)字節(jié),這個(gè)過程也就變成了所謂的gb2312編碼

如果上面的改為System.Text.Encoding.Default.GetBytes(param).Length,則值就是9和6了

如果需要了解更加深入的編碼內(nèi)部原理請(qǐng)參考:

http://blog.csdn.net/nodeathphoenix/article/details/7057760

  哈爾濱品用軟件有限公司致力于為哈爾濱的中小企業(yè)制作大氣、美觀的優(yōu)秀網(wǎng)站,并且能夠搭建符合百度排名規(guī)范的網(wǎng)站基底,使您的網(wǎng)站無需額外費(fèi)用,即可穩(wěn)步提升排名至首頁(yè)。歡迎體驗(yàn)最佳的哈爾濱網(wǎng)站建設(shè)。