国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
關(guān)于字符編碼,你所需要知道的

字符編碼的問(wèn)題看似很小,經(jīng)常被技術(shù)人員忽視,但是很容易導(dǎo)致一些莫名其妙的問(wèn)題。這里總結(jié)了一下字符編碼的一些普及性的知識(shí),希望對(duì)大家有所幫助。

還是得從ASCII碼說(shuō)起

 

說(shuō)到字符編碼,不得不說(shuō)ASCII碼的簡(jiǎn)史。計(jì)算機(jī)一開(kāi)始發(fā)明的時(shí)候是用來(lái)解決數(shù)字計(jì)算的問(wèn)題,后來(lái)人們發(fā)現(xiàn),計(jì)算機(jī)還可以做更多的事,例如文本處理。但由于計(jì)算機(jī)只識(shí)“數(shù)”,因此人們必須告訴計(jì)算機(jī)哪個(gè)數(shù)字來(lái)代表哪個(gè)特定字符,例如65代表字母‘A’,66代表字母‘B’,以此類(lèi)推。但是 計(jì)算機(jī)之間字符-數(shù)字的對(duì)應(yīng)關(guān)系必須得一致,否則就會(huì)造成同一段數(shù)字在不同計(jì)算機(jī)上顯示出來(lái)的字符不一樣 。因此美國(guó)國(guó)家標(biāo)準(zhǔn)協(xié)會(huì)ANSI制定了一個(gè)標(biāo)準(zhǔn),規(guī)定了常用字符的集合以及每個(gè)字符對(duì)應(yīng)的編號(hào),這就是ASCII字符集(Character Set),也稱(chēng)ASCII碼。

當(dāng)時(shí)的計(jì)算機(jī)普遍使用8比特字節(jié)作為最小的存儲(chǔ)和處理單元,加之當(dāng)時(shí)用到的字符也很少,26個(gè)大小寫(xiě)英文字母還有數(shù)字再加上其他常用符號(hào),也不到100個(gè),因此使用7個(gè)比特位就可以高效的存儲(chǔ)和處理ASCII碼,剩下最高位1比特被用作一些通訊系統(tǒng)的奇偶校驗(yàn)。

注意,字節(jié)代表系統(tǒng)能夠處理的最小單位,不一定是8比特。只是現(xiàn)代計(jì)算機(jī)的事實(shí)標(biāo)準(zhǔn)就是用8比特來(lái)代表一個(gè)字節(jié)。在很多技術(shù)規(guī)格文獻(xiàn)中,為了避免產(chǎn)生歧義,更傾向于使用8位組(Octet)而不是字節(jié)(Byte)這個(gè)術(shù)語(yǔ)來(lái)強(qiáng)調(diào)8個(gè)比特的二進(jìn)制流。下文中為了便于理解,我會(huì)延用大家熟悉的“字節(jié)”這個(gè)概念。

ASCII字符集由95個(gè)可打印字符(0x20-0x7E)和33個(gè)控制字符(0x00-0x19,0x7F)組成??纱蛴∽址糜陲@示在輸出設(shè)備上,例如熒屏或者打印紙上,控制字符用于向計(jì)算機(jī)發(fā)出一些特殊指令,例如0x07會(huì)讓計(jì)算機(jī)發(fā)出嗶的一聲,0x00通常用于指示字符串的結(jié)束,0x0D和0x0A用于指示打印機(jī)的打印針頭退到行首(回車(chē))并移到下一行(換行)。

那時(shí)候的字符編解碼系統(tǒng)非常簡(jiǎn)單,就是簡(jiǎn)單的查表過(guò)程。例如將字符序列編碼為二進(jìn)制流寫(xiě)入存儲(chǔ)設(shè)備,只需要在ASCII字符集中依次找到字符對(duì)應(yīng)的字節(jié),然后直接將該字節(jié)寫(xiě)入存儲(chǔ)設(shè)備即可。解碼二進(jìn)制流的過(guò)程也是類(lèi)似。

OEM字符集的衍生

當(dāng)計(jì)算機(jī)開(kāi)始發(fā)展起來(lái)的時(shí)候,人們逐漸發(fā)現(xiàn),ASCII字符集里那可憐的128個(gè)字符已經(jīng)不能再滿(mǎn)足他們的需求了。人們就在想,一個(gè)字節(jié)能夠表示的數(shù)字(編號(hào))有256個(gè),而ASCII字符只用到了0x00~0x7F,也就是占用了前128個(gè),后面128個(gè)數(shù)字不用白不用,因此很多人打起了后面這128個(gè)數(shù)字的主意??墒菃?wèn)題在于,很多人同時(shí)有這樣的想法,但是大家對(duì)于0x80-0xFF這后面的128個(gè)數(shù)字分別對(duì)應(yīng)什么樣的字符,卻有各自的想法。這就導(dǎo)致了當(dāng)時(shí)銷(xiāo)往世界各地的機(jī)器上出現(xiàn)了大量各式各樣的OEM字符集。

下面這張表是IBM-PC機(jī)推出的其中一個(gè)OEM字符集,字符集的前128個(gè)字符和ASCII字符集的基本一致(為什么說(shuō)基本一致呢,是因?yàn)榍?2個(gè)控制字符在某些情況下會(huì)被IBM-PC機(jī)當(dāng)作可打印字符解釋?zhuān)竺?28個(gè)字符空間加入了一些歐洲國(guó)家用到的重音字符,以及一些用于畫(huà)線(xiàn)條畫(huà)的字符。

事實(shí)上,大部分OEM字符集是兼容ASCII字符集的,也就是說(shuō),大家對(duì)于0x00~0x7F這個(gè)范圍的解釋基本是相同的,而對(duì)于后半部分0x80~0xFF的解釋卻不一定相同。甚至有時(shí)候同樣的字符在不同OEM字符集中對(duì)應(yīng)的字節(jié)也是不同的。

不同的OEM字符集導(dǎo)致人們無(wú)法跨機(jī)器交流各種文檔。例如職員甲發(fā)了一封簡(jiǎn)歷résumés給職員乙,結(jié)果職員乙看到的卻是r

sum
s,因?yàn)?#233;字符在職員甲機(jī)器上的OEM字符集中對(duì)應(yīng)的字節(jié)是0x82,而在職員乙的機(jī)器上,由于使用的OEM字符集不同,對(duì)0x82字節(jié)解碼后得到的字符卻是
。

多字節(jié)字符集(MBCS)和中文字符集

上面我們提到的字符集都是基于單字節(jié)編碼,也就是說(shuō),一個(gè)字節(jié)翻譯成一個(gè)字符。這對(duì)于拉丁語(yǔ)系國(guó)家來(lái)說(shuō)可能沒(méi)有什么問(wèn)題,因?yàn)樗麄兺ㄟ^(guò)擴(kuò)展第8個(gè)比特,就可以得到256個(gè)字符了,足夠用了。但是對(duì)于亞洲國(guó)家來(lái)說(shuō),256個(gè)字符是遠(yuǎn)遠(yuǎn)不夠用的。因此這些國(guó)家的人為了用上電腦,又要保持和ASCII字符集的兼容,就發(fā)明了多字節(jié)編碼方式,相應(yīng)的字符集就稱(chēng)為多字節(jié)字符集。例如中國(guó)使用的就是雙字節(jié)字符集編碼(DBCS,Double ByteCharacter Set)。

對(duì)于單字節(jié)字符集來(lái)說(shuō),代碼頁(yè)中只需要有一張碼表即可,上面記錄著256個(gè)數(shù)字代表的字符。程序只需要做簡(jiǎn)單的查表操作就可以完成編解碼的過(guò)程。

代碼頁(yè)是字符集編碼的具體實(shí)現(xiàn),你可以把他理解為一張“字符-字節(jié)”映射表,通過(guò)查表實(shí)現(xiàn)“字符-字節(jié)”的翻譯。下面會(huì)有更詳細(xì)的描述。

而對(duì)于多字節(jié)字符集,代碼頁(yè)中通常會(huì)有很多碼表。那么程序怎么知道該使用哪張碼表去解碼二進(jìn)制流呢?答案是, 根據(jù)第一個(gè)字節(jié)來(lái)選擇不同的碼表進(jìn)行解析

例如目前最常用的中文字符集GB2312,涵蓋了所有簡(jiǎn)體字符以及一部分其他字符;GBK(K代表擴(kuò)展的意思)則在GB2312的基礎(chǔ)上加入了對(duì)繁體字符等其他非簡(jiǎn)體字符(GB18030字符集不是雙字節(jié)字符集,我們?cè)谥vUnicode的時(shí)候會(huì)提到)。這兩個(gè)字符集的字符都是使用1-2個(gè)字節(jié)來(lái)表示。Windows系統(tǒng)采用936代碼頁(yè)來(lái)實(shí)現(xiàn)對(duì)GBK字符集的編解碼。在解析字節(jié)流的時(shí)候,如果遇到字節(jié)的最高位是0的話(huà),那么就使用936代碼頁(yè)中的第1張碼表進(jìn)行解碼,這就和單字節(jié)字符集的編解碼方式一致了。

當(dāng)字節(jié)的高位是1的時(shí)候,確切的說(shuō),當(dāng)?shù)谝粋€(gè)字節(jié)位于0x81–0xFE之間時(shí),根據(jù)第一個(gè)字節(jié)不同找到代碼頁(yè)中的相應(yīng)的碼表,例如當(dāng)?shù)谝粋€(gè)字節(jié)是0x81,那么對(duì)應(yīng)936中的下面這張碼表:

(關(guān)于936代碼頁(yè)中完整的碼表信息,參見(jiàn)MSDN:http://msdn.microsoft.com/en-us/library/cc194913%28v=MSDN.10%29.aspx.)

按照936代碼頁(yè)的碼表,當(dāng)程序遇到連續(xù)字節(jié)流0x81 0x40的時(shí)候,就會(huì)解碼為“丂”字符。

ANSI標(biāo)準(zhǔn)、國(guó)家標(biāo)準(zhǔn)、ISO標(biāo)準(zhǔn)

不同ASCII衍生字符集的出現(xiàn),讓文檔交流變得非常困難,因此各種組織都陸續(xù)進(jìn)行了標(biāo)準(zhǔn)化流程。例如美國(guó)ANSI組織制定了ANSI標(biāo)準(zhǔn)字符編碼(注意, 我們現(xiàn)在通常說(shuō)到ANSI編碼,通常指的是平臺(tái)的默認(rèn)編碼,例如英文操作系統(tǒng)中是ISO-8859-1,中文系統(tǒng)是GBK ),ISO組織制定的各種ISO標(biāo)準(zhǔn)字符編碼,還有各國(guó)也會(huì)制定一些國(guó)家標(biāo)準(zhǔn)字符集,例如中國(guó)的GBK,GB2312和GB18030。

操作系統(tǒng)在發(fā)布的時(shí)候,通常會(huì)往機(jī)器里預(yù)裝這些標(biāo)準(zhǔn)的字符集還有平臺(tái)專(zhuān)用的字符集,這樣只要你的文檔是使用標(biāo)準(zhǔn)字符集編寫(xiě)的,通用性就比較高了。例如你用GB2312字符集編寫(xiě)的文檔,在中國(guó)大陸內(nèi)的任何機(jī)器上都能正確顯示。同時(shí),我們也可以在一臺(tái)機(jī)器上閱讀多個(gè)國(guó)家不同語(yǔ)言的文檔了,前提是本機(jī)必須安裝該文檔使用的字符集。

Unicode的出現(xiàn)

雖然通過(guò)使用不同字符集,我們可以在一臺(tái)機(jī)器上查閱不同語(yǔ)言的文檔,但是我們?nèi)匀粺o(wú)法解決一個(gè)問(wèn)題: 在一份文檔中顯示所有字符 。為了解決這個(gè)問(wèn)題,我們需要一個(gè)全人類(lèi)達(dá)成共識(shí)的巨大的字符集,這就是Unicode字符集。

Unicode字符集概述

Unicode字符集涵蓋了目前人類(lèi)使用的所有字符,并為每個(gè)字符進(jìn)行統(tǒng)一編號(hào),分配唯一的字符碼(CodePoint)。Unicode字符集將所有字符按照使用上的頻繁度劃分為17個(gè)層面(Plane),每個(gè)層面上有216=65536個(gè)字符碼空間。

其中第0個(gè)層面BMP,基本涵蓋了當(dāng)今世界用到的所有字符。其他的層面要么是用來(lái)表示一些遠(yuǎn)古時(shí)期的文字,要么是留作擴(kuò)展。我們平常用到的Unicode字符,一般都是位于BMP層面上的。目前Unicode字符集中尚有大量字符空間未使用。

編碼系統(tǒng)的變化

在Unicode出現(xiàn)之前,所有的字符集都是和具體編碼方案綁定在一起的,都是直接將字符和最終字節(jié)流綁定死了,例如ASCII編碼系統(tǒng)規(guī)定使用7比特來(lái)編碼ASCII字符集;GB2312以及GBK字符集,限定了使用最多2個(gè)字節(jié)來(lái)編碼所有字符,并且規(guī)定了字節(jié)序。這樣的編碼系統(tǒng)通常用簡(jiǎn)單的查表,也就是通過(guò)代碼頁(yè)就可以直接將字符映射為存儲(chǔ)設(shè)備上的字節(jié)流了。例如下面這個(gè)例子:

這種方式的缺點(diǎn)在于,字符和字節(jié)流之間耦合得太緊密了,從而限定了字符集的擴(kuò)展能力。假設(shè)以后火星人入住地球了,要往現(xiàn)有字符集中加入火星文就變得很難甚至不可能了,而且很容易破壞現(xiàn)有的編碼規(guī)則。

因此Unicode在設(shè)計(jì)上考慮到了這一點(diǎn),將字符集和字符編碼方案分離開(kāi)。

也就是說(shuō), 雖然每個(gè)字符在Unicode字符集中都能找到唯一確定的編號(hào)(字符碼,又稱(chēng)Unicode碼),但是決定最終字節(jié)流的卻是具體的字符編碼 。例如同樣是對(duì)Unicode字符“A”進(jìn)行編碼,UTF-8字符編碼得到的字節(jié)流是0x41,而UTF-16(大端模式)得到的是0x00 0x41。

常見(jiàn)的Unicode編碼

UCS-2/UTF-16

如果要我們來(lái)實(shí)現(xiàn)Unicode字符集中BMP字符的編碼方案,我們會(huì)怎么實(shí)現(xiàn)?由于BMP層面上有216=65536個(gè)字符碼,因此我們只需要兩個(gè)字節(jié)就可以完全表示這所有的字符了。

舉個(gè)例子,“中”的Unicode字符碼是0x4E2D(01001110 00101101),那么我們可以編碼為0100111000101101(大端)或者00101101 01001110 (小端)。

UCS-2和UTF-16對(duì)于BMP層面的字符均是使用2個(gè)字節(jié)來(lái)表示,并且編碼得到的結(jié)果完全一致。不同之處在于, UCS-2最初設(shè)計(jì)的時(shí)候只考慮到BMP字符,因此使用固定2個(gè)字節(jié)長(zhǎng)度,也就是說(shuō),他無(wú)法表示Unicode其他層面上的字符,而UTF-16為了解除這個(gè)限制,支持Unicode全字符集的編解碼,采用了變長(zhǎng)編碼,最少使用2個(gè)字節(jié),如果要編碼BMP以外的字符,則需要4個(gè)字節(jié)結(jié)對(duì) ,這里就不討論那么遠(yuǎn),有興趣可以參考維基百科:UTF-16/UCS-2。

Windows從NT時(shí)代開(kāi)始就采用了UTF-16編碼,很多流行的編程平臺(tái),例如.Net,Java,Qt還有Mac下的Cocoa等都是使用UTF-16作為基礎(chǔ)的字符編碼。例如代碼中的字符串,在內(nèi)存中相應(yīng)的字節(jié)流就是用UTF-16編碼過(guò)的。

UTF-8

UTF-8應(yīng)該是目前應(yīng)用最廣泛的一種Unicode編碼方案。由于UCS-2/UTF-16對(duì)于ASCII字符使用兩個(gè)字節(jié)進(jìn)行編碼,存儲(chǔ)和處理效率相對(duì)低下,并且由于ASCII字符經(jīng)過(guò)UTF-16編碼后得到的兩個(gè)字節(jié),高字節(jié)始終是0x00,很多C語(yǔ)言的函數(shù)都將此字節(jié)視為字符串末尾從而導(dǎo)致無(wú)法正確解析文本。因此一開(kāi)始推出的時(shí)候遭到很多西方國(guó)家的抵觸,大大影響了Unicode的推行。后來(lái)聰明的人們發(fā)明了UTF-8編碼,解決了這個(gè)問(wèn)題。

UTF-8編碼方案采用1-4個(gè)字節(jié)來(lái)編碼字符,方法其實(shí)也非常簡(jiǎn)單。

(上圖中的x代表Unicode碼的低8位,y代表高8位)

對(duì)于ASCII字符的編碼使用單字節(jié),和ASCII編碼一摸一樣,這樣所有原先使用ASCII編解碼的文檔就可以直接轉(zhuǎn)到UTF-8編碼了。對(duì)于其他字符,則使用2-4個(gè)字節(jié)來(lái)表示,其中,首字節(jié)前置1的數(shù)目代表正確解析所需要的字節(jié)數(shù),剩余字節(jié)的高2位始終是10。例如首字節(jié)是1110yyyy,前置有3個(gè)1,說(shuō)明正確解析總共需要3個(gè)字節(jié),需要和后面2個(gè)以10開(kāi)頭的字節(jié)結(jié)合才能正確解析得到字符 。

關(guān)于UTF-8的更多信息,參考維基百科:UTF-8。

GB18030

任何能夠?qū)nicode字符映射為字節(jié)流的編碼都屬于Unicode編碼。中國(guó)的GB18030編碼,覆蓋了Unicode所有的字符,因此也算是一種Unicode編碼。只不過(guò)他的編碼方式并不像UTF-8或者UTF-16一樣,將Unicode字符的編號(hào)通過(guò)一定的規(guī)則進(jìn)行轉(zhuǎn)換,而只能通過(guò)查表的手段進(jìn)行編碼。

關(guān)于GB18030的更多信息,參考:GB18030。

Unicode相關(guān)的常見(jiàn)問(wèn)題

Unicode是兩個(gè)字節(jié)嗎?

Unicode只是定義了一個(gè)龐大的、全球通用的字符集,并為每個(gè)字符規(guī)定了唯一確定的編號(hào),具體存儲(chǔ)為什么樣的字節(jié)流,取決于字符編碼方案。推薦的Unicode編碼是UTF-16和UTF-8。

帶簽名的UTF-8指的是什么意思?

帶簽名指的是字節(jié)流以BOM標(biāo)記開(kāi)始。很多軟件會(huì)“智能”的探測(cè)當(dāng)前字節(jié)流使用的字符編碼,這種探測(cè)過(guò)程出于效率考慮,通常會(huì)提取字節(jié)流前面若干個(gè)字節(jié),看看是否符合某些常見(jiàn)字符編碼的編碼規(guī)則。由于UTF-8和ASCII編碼對(duì)于純英文的編碼是一樣的,無(wú)法區(qū)分開(kāi)來(lái),因此通過(guò)在字節(jié)流最前面添加BOM標(biāo)記可以告訴軟件,當(dāng)前使用的是Unicode編碼,判別成功率就十分準(zhǔn)確了。但是需要注意,不是所有軟件或者程序都能正確處理BOM標(biāo)記,例如PHP就不會(huì)檢測(cè)BOM標(biāo)記,直接把它當(dāng)普通字節(jié)流解析了。因此如果你的PHP文件是采用帶BOM標(biāo)記的UTF-8進(jìn)行編碼的,那么有可能會(huì)出現(xiàn)問(wèn)題。

Unicode編碼和以前的字符集編碼有什么區(qū)別?

早期字符編碼、字符集和代碼頁(yè)等概念都是表達(dá)同一個(gè)意思。例如GB2312字符集、GB2312編碼,936代碼頁(yè),實(shí)際上說(shuō)的是同個(gè)東西。但是對(duì)于Unicode則不同,Unicode字符集只是定義了字符的集合和唯一編號(hào),Unicode編碼,則是對(duì)UTF-8、UCS-2/UTF-16等具體編碼方案的統(tǒng)稱(chēng)而已,并不是具體的編碼方案。所以當(dāng)需要用到字符編碼的時(shí)候,你可以寫(xiě)gb2312,codepage936,utf-8,utf-16,但請(qǐng)不要寫(xiě)unicode(看過(guò)別人在網(wǎng)頁(yè)的meta標(biāo)簽里頭寫(xiě)charset=unicode,有感而發(fā))。

 

亂碼問(wèn)題

亂碼指的是程序顯示出來(lái)的字符文本無(wú)法用任何語(yǔ)言去解讀。一般情況下會(huì)包含大量?或者?。亂碼問(wèn)題是所有計(jì)算機(jī)用戶(hù)或多或少會(huì)遇到的問(wèn)題。 造成亂碼的原因就是因?yàn)槭褂昧隋e(cuò)誤的字符編碼去解碼字節(jié)流 , 因此當(dāng)我們?cè)谒伎既魏胃谋撅@示有關(guān)的問(wèn)題時(shí),請(qǐng)時(shí)刻保持清醒:當(dāng)前使用的字符編碼是什么 。只有這樣,我們才能正確分析和處理亂碼問(wèn)題。

例如最常見(jiàn)的網(wǎng)頁(yè)亂碼問(wèn)題。如果你是網(wǎng)站技術(shù)人員,遇到這樣的問(wèn)題,需要檢查以下原因:

  • 服務(wù)器返回的響應(yīng)頭Content-Type沒(méi)有指明字符編碼
  • 網(wǎng)頁(yè)內(nèi)是否使用META HTTP-EQUIV標(biāo)簽指定了字符編碼
  • 網(wǎng)頁(yè)文件本身存儲(chǔ)時(shí)使用的字符編碼和網(wǎng)頁(yè)聲明的字符編碼是否一致  

注意,網(wǎng)頁(yè)解析的過(guò)程如果使用的字符編碼不正確,還可能會(huì)導(dǎo)致腳本或者樣式表出錯(cuò)。具體細(xì)節(jié)可以參考我以前寫(xiě)過(guò)的文章:文檔字符集導(dǎo)致的腳本錯(cuò)誤Asp.Net頁(yè)面的編碼問(wèn)題。

不久前看到某技術(shù)論壇有人反饋,WinForm程序使用Clipboard類(lèi)的GetData方法去訪(fǎng)問(wèn)剪切板中的HTML內(nèi)容時(shí)會(huì)出現(xiàn)亂碼的問(wèn)題,我估計(jì)也是由于WinForm在獲取HTML文本的時(shí)候沒(méi)有用對(duì)正確的字符編碼導(dǎo)致的。Windows剪貼板只支持UTF-8編碼,也就是說(shuō)你傳入的文本都會(huì)被UTF-8編解碼。這樣一來(lái),只要兩個(gè)程序都是調(diào)用Windows剪切板API編程的話(huà),那么復(fù)制粘貼的過(guò)程中不會(huì)出現(xiàn)亂碼。除非一方在獲取到剪貼板數(shù)據(jù)之后使用了錯(cuò)誤的字符編碼進(jìn)行解碼,才會(huì)得到亂碼(我做了簡(jiǎn)單的WinForm剪切板編程實(shí)驗(yàn),發(fā)現(xiàn)GetData使用的是系統(tǒng)默認(rèn)編碼,而不是UTF-8編碼)。

關(guān)于亂碼中出現(xiàn)?或者?,這里需要額外提一下, 當(dāng)程序使用特定字符編碼解析字節(jié)流的時(shí)候,一旦遇到無(wú)法解析的字節(jié)流時(shí),就會(huì)用?或者?來(lái)替代。因此,一旦你最終解析得到的文本包含這樣的字符,而你又無(wú)法得到原始字節(jié)流的時(shí)候,說(shuō)明正確的信息已經(jīng)徹底丟失了,嘗試任何字符編碼都無(wú)法從這樣的字符文本中還原出正確的信息來(lái)

必要的術(shù)語(yǔ)解釋

字符集(Character Set) ,字面上的理解就是字符的集合,例如ASCII字符集,定義了128個(gè)字符;GB2312定義了7445個(gè)字符。而 計(jì)算機(jī)系統(tǒng)中提到的字符集準(zhǔn)確來(lái)說(shuō),指的是已編號(hào)的字符的有序集合(不一定是連續(xù)) 。

字符碼(Code Point) 指的就是字符集中每個(gè)字符的數(shù)字編號(hào)。例如ASCII字符集用0-127這連續(xù)的128個(gè)數(shù)字分別表示128個(gè)字符;GBK字符集使用區(qū)位碼的方式為每個(gè)字符編號(hào),首先定義一個(gè)94X94的矩陣,行稱(chēng)為“區(qū)”,列稱(chēng)為“位”,然后將所有國(guó)標(biāo)漢字放入矩陣當(dāng)中,這樣每個(gè)漢字就可以用唯一的“區(qū)位”碼來(lái)標(biāo)識(shí)了。例如“中”字被放到54區(qū)第48位,因此字符碼就是5448。而Unicode中將字符集按照一定的類(lèi)別劃分到0~16這17個(gè)層面(Planes)中,每個(gè)層面中擁有216=65536個(gè)字符碼,因此Unicode總共擁有的字符碼,也即是Unicode的字符空間總共有17*65536=1114112。

編碼 的過(guò)程是將字符轉(zhuǎn)換成字節(jié)流。

解碼 的過(guò)程是將字節(jié)流解析為字符。

字符編碼(Character Encoding) 是將字符集中的字符碼映射為字節(jié)流的一種具體實(shí)現(xiàn)方案。例如ASCII字符編碼規(guī)定使用單字節(jié)中低位的7個(gè)比特去編碼所有的字符。例如‘A’的編號(hào)是65,用單字節(jié)表示就是0x41,因此寫(xiě)入存儲(chǔ)設(shè)備的時(shí)候就是b’01000001’。GBK編碼則是將區(qū)位碼(GBK的字符碼)中的區(qū)碼和位碼的分別加上0xA0(160)的偏移(之所以要加上這樣的偏移,主要是為了和ASCII碼兼容),例如剛剛提到的“中”字,區(qū)位碼是5448,十六進(jìn)制是0x3630,區(qū)碼和位碼分別加上0xA0的偏移之后就得到0xD6D0,這就是“中”字的GBK編碼結(jié)果。

代碼頁(yè)(Code Page) 一種字符編碼具體形式。早期字符相對(duì)少,因此通常會(huì)使用類(lèi)似表格的形式將字符直接映射為字節(jié)流,然后通過(guò)查表的方式來(lái)實(shí)現(xiàn)字符的編解碼。現(xiàn)代操作系統(tǒng)沿用了這種方式。例如Windows使用936代碼頁(yè)、Mac系統(tǒng)使用EUC-CN代碼頁(yè)實(shí)現(xiàn)GBK字符集的編碼,名字雖然不一樣,但對(duì)于同一漢字的編碼肯定是一樣的。

大小端 的說(shuō)法源自《格列佛游記》。我們知道,雞蛋通常一端大一端小,小人國(guó)的人們對(duì)于剝蛋殼時(shí)應(yīng)從哪一端開(kāi)始剝起有著不一樣的看法。同樣,計(jì)算機(jī)界對(duì)于傳輸多字節(jié)字(由多個(gè)字節(jié)來(lái)共同表示一個(gè)數(shù)據(jù)類(lèi)型)時(shí),是先傳高位字節(jié)(大端)還是先傳低位字節(jié)(小端)也有著不一樣的看法,這就是計(jì)算機(jī)里頭大小端模式的由來(lái)了。無(wú)論是寫(xiě)文件還是網(wǎng)絡(luò)傳輸,實(shí)際上都是往流設(shè)備進(jìn)行寫(xiě)操作的過(guò)程,而且這個(gè)寫(xiě)操作是從流的低地址向高地址開(kāi)始寫(xiě)(這很符合人的習(xí)慣),對(duì)于多字節(jié)字來(lái)說(shuō),如果先寫(xiě)入高位字節(jié),則稱(chēng)作大端模式。反之則稱(chēng)作小端模式。也就是說(shuō),大端模式下,字節(jié)序和流設(shè)備的地址順序是相反的,而小端模式則是相同的。一般網(wǎng)絡(luò)協(xié)議都采用大端模式進(jìn)行傳輸。


本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Python 編碼錯(cuò)誤的本質(zhì)原因
女朋友問(wèn)我:為什么會(huì)亂碼?
Unicode,GBK和UTF8
不可不知的Python字符編碼使用技巧(上)
ASCII, GB2312, Unicode , UTF-8 - 靈感點(diǎn)滴
計(jì)算機(jī)編碼基礎(chǔ)知識(shí)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服