少高潮爽了在观看奂费_奶水无码专区_欧美亚洲三级日韩_91精品国产综合香蕉_秋霞伦理电影在线_GOGO亚洲肉体艺术欣赏图片_一本一道a√无码中文字幕_免费看一级毛片无码区_内射视频网站在线观看_国产激情视频精品中文

編程代碼
新聞詳情

萬字長文講解編碼知識,看這文就夠了?。ㄒ唬?/h1> 發(fā)布時間:2020-05-31 09:58:33 最后更新:2020-11-23 14:37:09 瀏覽次數(shù):2761

萬字長文講解編碼知識,看這文就夠了!| 原力計劃


基礎(chǔ)概念

1、字符

字符指類字形單位或符號,包括字母、數(shù)字、運(yùn)算符號、標(biāo)點符號和其他符號,以及一些功能性符號。一般來說我們稱某個字符集里面的字符,叫xx字符,如ASCII字符集里面的ASCII字符,GB2312字符集里面的GB2312字符。

2、字符集

字符集(Character Set、Charset),字面上的理解就是字符的集合,是一個自然語言文字系統(tǒng)支持的所有字符的集合。字符是各種文字和符號的總稱,包括文字、數(shù)字、字母、音節(jié)、標(biāo)點符號、圖形符號等。例如ASCII字符集,定義了128個字符;GB2312字符集定義了7445個字符。而字符集準(zhǔn)確地來說,指的是已編號的字符的有序集合(但不一定是連續(xù)的,后文有詳細(xì)介紹)。

常見字符集名稱:ASCII字符集、GB2312字符集、BIG5字符集、 GB18030字符集、Unicode字符集等。

3、碼位

在字符編碼術(shù)語中,碼位(code point)或稱編碼位置、碼點,是組成碼空間(或代碼頁)的數(shù)值。例如,ASCII碼包含128個碼位,范圍是016進(jìn)制到7F16進(jìn)制,擴(kuò)展ASCII碼包含256個碼位,范圍是016進(jìn)制到FF16進(jìn)制,而Unicode包含1,114,112個碼位,范圍是016進(jìn)制到10FFFF16進(jìn)制。Unicode碼空間劃分為17個Unicode字符平面(基本多文種平面,16個輔助平面),每個平面有65,536(= 216)個碼位。因此Unicode碼空間總計是17 × 65,536 = 1,114,112. —解釋來源于維基百科。

4、字符編碼

字符編碼(Character Encoding),是把字符集中的字符按一定方式編碼為某指定集合中的某一對象的過程(比如將字符編碼為由0和1兩個數(shù)字所組成的位串模式、由0~9十個數(shù)字所組成的自然數(shù)序列或電脈沖等),亦即在字符集與指定集合兩者之間建立一個對應(yīng)關(guān)系(即映射關(guān)系)的過程。這是信息處理的一項基礎(chǔ)技術(shù)。常見的例子包括將拉丁字母表編碼成摩斯電碼和ASCII碼。

PS:這里我們計算機(jī)這里字符編碼肯定是用二進(jìn)制來編碼的。

看完這四個概念,你應(yīng)該要明白,它們之間的關(guān)系,以ASCII為例,下圖解釋它們之間關(guān)系。

萬字長文講解編碼知識,看這文就夠了!| 原力計劃

這里細(xì)說一下,碼位就是這個字符集里面字符的一個表示位置,通俗來說,碼位就是一般跟字符集綁在一起,字符編碼是把字符集中的字符編碼為特定的二進(jìn)制數(shù),以便在計算機(jī)中存儲。這個二進(jìn)制數(shù)就叫xx碼。

字符集編碼分類總結(jié)

在說字符集編碼之前,先明確一個觀點,字符集編碼與字符集是兩個不同層面的概念:

(1)charset 是character set 的簡寫,即字符集。

(2)encoding 是 charsetencoding 的簡寫,即字符集編碼,簡稱編碼。

萬字長文講解編碼知識,看這文就夠了!| 原力計劃

1、ASCII編碼

ASCII(美國信息交換標(biāo)準(zhǔn)代碼)是基于拉丁字母(就是我們現(xiàn)在的英文字母)的一套電腦編碼系統(tǒng)。它主要用于顯示現(xiàn)代英語,而其擴(kuò)展版本延伸美國標(biāo)準(zhǔn)信息交換碼則可以部分支持其他西歐語言,并等同于國際標(biāo)準(zhǔn)ISO/IEC 646。

ASCII由電報碼發(fā)展而來。第一版標(biāo)準(zhǔn)發(fā)布于1963年,1967年經(jīng)歷了一次主要修訂,最后一次更新則是在1986年,至今為止共定義了128個字符;其中33個字符無法顯示(一些終端提供了擴(kuò)展,使得這些字符可顯示為諸如笑臉、撲克牌花式等8-bit符號),且這33個字符多數(shù)都已是陳廢的控制字符??刂谱址挠猛局饕怯脕聿倏匾呀?jīng)處理過的文字。在33個字符之外的是95個可顯示的字符。用鍵盤敲下空白鍵所產(chǎn)生的空白字符也算1個可顯示字符(顯示為空白)。

每個ASCII字符占用1個字節(jié)(8bits),共有128位字符或符號,使用7位二進(jìn)制數(shù)(剩下的1位二進(jìn)制為0,即高位為0)來表示所有的大寫和小寫字母,數(shù)字0 到9、標(biāo)點符號,以及在美式英語中使用的特殊控制字符。

缺點:ASCII的最大缺點是只能顯示26個基本拉丁字母、阿拉伯?dāng)?shù)目字和英式標(biāo)點符號,因此只能用于顯示現(xiàn)代美國英語(而且在處理英語當(dāng)中的外來詞如na?ve、café、élite等等時,所有重音符號都不得不去掉,即使這樣做會違反拼寫規(guī)則)。而EASCII(即擴(kuò)展的ASCII碼,利用8位的高位設(shè)為1進(jìn)行擴(kuò)展)雖然解決了部分西歐語言的顯示問題,但對更多其他語言依然無能為力。因此現(xiàn)在的操作系統(tǒng)內(nèi)碼(稍后會講)基本已經(jīng)拋棄ASCII碼而轉(zhuǎn)用Unicode碼。

ASCII碼表 :http://www.asciitable.com

2、GB2312編碼

前面可以看到ASCII碼即使進(jìn)行了擴(kuò)展也能表示的字符也很少,尤其是當(dāng)需要計算機(jī)顯示存儲中文的時候,就需要一種對中文進(jìn)行編碼的字符集,GB 2312就是解決中文編碼的字符集,由國家標(biāo)準(zhǔn)委員會發(fā)布。那個時候當(dāng)中國人們得到計算機(jī)時,已經(jīng)沒有可以利用的字節(jié)狀態(tài)來表示漢字,況且有6000多個常用漢字需要保存,于是想到把那些ASCII碼中127號之后的奇異符號們直接取消掉, 規(guī)定:一個小于127的字符的意義與原來相同,但兩個大于127的字符連在一起時,就表示一個漢字,前面的一個字節(jié)(稱之為高字節(jié))從0xA1用到0xF7,后面一個字節(jié)(低字節(jié))從0xA1到0xFE,這樣我們就可以組合出大約7000多個簡體漢字了。在這些編碼里,我們還把數(shù)學(xué)符號、羅馬希臘的字母、日文的假名們都編進(jìn)去了,連在 ASCII 里本來就有的數(shù)字、標(biāo)點、字母都統(tǒng)統(tǒng)重新編了兩個字節(jié)長的編碼,這就是常說的"全角"字符,而原來在127號以下的那些就叫"半角"字符了。這種漢字方案叫做 “GB2312”。GB2312 是對ASCII 的中文擴(kuò)展。兼容ASCII。

萬字長文講解編碼知識,看這文就夠了!| 原力計劃

這里的A GB2312碼是0xA3C1,0xA3和0xC1都是高于127的,所以判斷它是個全角字符,另外我們可以觀察到所有的GB2312編碼表中的GB2312碼每個字節(jié)都是大于0xA0的,這個就是為了保證能區(qū)分是否為ASCII碼,小于127的字節(jié)就按照ASCII碼標(biāo)準(zhǔn),碰到連續(xù)兩個大于127字節(jié)就組合成一個GB2312碼。

GB2312漢字編碼字符集對照表:
http://tools.jb51.net/table/gb2312

3、GBK編碼

但是中國的漢字太多了,我們很快就就發(fā)現(xiàn)有許多人的人名沒有辦法在這里打出來,不得不繼續(xù)把 GB2312 沒有用到的碼位找出來用上。后來還是不夠用,于是干脆不再要求低字節(jié)一定是127號之后的內(nèi)碼,只要第一個字節(jié)是大于127就固定表示這是一個漢字的開始,不管后面跟的是不是擴(kuò)展字符集里的內(nèi)容。結(jié)果擴(kuò)展之后的編碼方案被稱為 “GBK” 標(biāo)準(zhǔn),GBK 包括了GB2312 的所有內(nèi)容,同時又增加了近20000個新的漢字(包括繁體字)和符號。

4、GB18030編碼

后來中國的少數(shù)民族也要用電腦了,GBK的兩萬多字也已經(jīng)無法滿足我們的需求了,還有更多可能你自己從來沒見過的漢字需要編碼。這時候顯然只用2bytes表示一個字已經(jīng)不夠用了(2byte最多只有65536種組合,然而為了和ASCII兼容,最高位不能為0就已經(jīng)直接淘汰了一半的組合,只剩下3萬多種組合無法滿足全部漢字要求)。因此GB18030多出來的漢字使用4byte編碼。

當(dāng)然,為了兼容GBK,這個四字節(jié)的前兩位顯然不能與GBK沖突(實操中發(fā)現(xiàn)后兩位也并沒有和GBK沖突)。通過多年的發(fā)展至此,GB18030編碼的中文文件已經(jīng)有七萬多個漢字了。

GB18030包含三種長度的編碼:單字節(jié)的ASCII、雙字節(jié)的GBK(略帶擴(kuò)展)、以及用于填補(bǔ)所有Unicode碼位的四字節(jié)UTF區(qū)塊。所以我們說GB18030采用多字節(jié)編碼,每個字符可以由 1 個、2 個或 4 個字節(jié)組成

其實我們用到的99%以上的漢字,都在GB2312那一塊區(qū)域內(nèi)。在實際使用中,GBK編碼已經(jīng)可以滿足大部分場景了,GB18030編碼中所有漢字都是我們這輩子都不一定能見到的文字,所以平時經(jīng)常會使用的就是GBK編碼。

這里額外總結(jié)一下這四個兼容性關(guān)系是GB18030兼容GBK,GBK兼容GB2312,GB2312兼容ASCII。所謂兼容,你可以簡單理解為子集、不沖突的關(guān)系。

例如GB2312編碼的文件中可以出現(xiàn)ASCII字符,GBK編碼的文件中可以出現(xiàn)GB2312和ASCII字符,GB18030編碼的文件可以出現(xiàn)GBK、GB2312、ASCII字符。

5、Unicode

友情建議:看Unicode一些概念解釋和歷史時,建議看維基百科,而且是英文版的,別用中文版,有些地方講的模棱兩可,容易陷入盲區(qū)。

Unicode(中文:萬國碼、國際碼、統(tǒng)一碼、單一碼)(全稱Universal Multiple-Octet Coded Character Set)它伴隨著通用字符集(英語:Universal Character Set, UCS)的標(biāo)準(zhǔn)而發(fā)展。所以可以看出他是字符集。

(1)Unicode與 ISO 10646

全世界很多個國家都在為自己的文字編碼,并且互不相通,不同的語言字符編碼值相同卻代表不同的符號(例如:韓文編碼EUC-KR中“???”的編碼值正好是漢字編碼GBK中的“茄憊絹”)。

因此,同一份文檔,拷貝至不同語言的機(jī)器,就可能成了亂碼,于是人們就想:我們能不能定義一個超大的字符集,它可以容納全世界所有的文字字符,再對它們統(tǒng)一進(jìn)行編碼,讓每一個字符都對應(yīng)一個不同的編碼值,從而就不會再有亂碼了。

如果說“各個國家都在為自己文字獨立編碼”是百家爭鳴,那么“建立世界統(tǒng)一的字符編碼”則是一統(tǒng)江湖,誰都想來做這個武林盟主。早前就有兩個機(jī)構(gòu)做了這個事:

  • 國際標(biāo)準(zhǔn)化組織(ISO),他們于1984年創(chuàng)建ISO/IEC JTC1/SC2/WG2工作組,試圖制定一份“通用字符集”(Universal Character Set,簡稱UCS),并最終制定了ISO 10646標(biāo)準(zhǔn)。(簡單來說ISO 10646標(biāo)準(zhǔn)就是UCS)

  • 統(tǒng)一碼聯(lián)盟,他們由Xerox、Apple等軟件制造商于1988年組成,并且開發(fā)了Unicode標(biāo)準(zhǔn)(The Unicode Standard,這個前綴Uni很牛逼哦—Unique, Universal, and Uniform)。

Unicode與ISO 10646標(biāo)準(zhǔn)的風(fēng)風(fēng)雨雨:

在1984年,喜歡以繁多的編號糊弄群眾的國際標(biāo)準(zhǔn)化組織ISO也開始著手制定解決不同語言字符數(shù)量太大問題的解決方案,這一方案被稱為Universal Character Set(UCS),正式的編號是ISO-10646(記得么,ASCII是ISO-646,不知這種安排是否是故意的)。

還是ISO高瞻遠(yuǎn)矚,一開始就確定了UCS是一個31位的編碼字符集(即用一個大小不超過2的31次方的整數(shù)數(shù)字為每個字符編號),這回真的足以容納古往今來所有國家,所有語言所包含的字符了(是的,任何國家,任何小語種都包括)。雖然后來他們意識到,2的31次方個碼位又實在太多了……

天下大勢,分久必合。無論Unicode還是UCS,最初的目的都是杜絕各種各樣名目繁多形式各異互不兼容老死不相往來的私用擴(kuò)展編碼(好啰嗦的一句話),結(jié)果兩方確立標(biāo)準(zhǔn)的同時(最初時這兩個標(biāo)準(zhǔn)是不兼容的),因為都是個干個的,肯定不可能一模一樣,出現(xiàn)標(biāo)準(zhǔn)不同。

1991年,Unicode聯(lián)盟與ISO的工作組終于開始討論Unicode與UCS的合并問題,雖然其后的合并進(jìn)行了很多年,Unicode初版規(guī)范中的很多編碼都需要被改寫,UCS也需要對碼空間的使用進(jìn)行必要限制,但成果是喜人的。

最終,兩者統(tǒng)一了抽象字符集(即任何一個在Unicode中存在的字符,在UCS中也存在),且最靠前的65535個字符也統(tǒng)一了字符的編碼。對于碼空間,兩者同意以一百一十萬為限(即兩者都認(rèn)為雖然65536不夠,但2的31次方又太大,一百一十萬是個雙方都可接受的碼空間大小,也夠用,當(dāng)然,這里說的一百一十萬只是個約數(shù)),Unicode將碼空間擴(kuò)展到了一百一十萬,而UCS將永久性的不使用一百一十萬以后的碼位。

也就是說,現(xiàn)在再講Unicode只包含65536個字符是不對的(雖然大家現(xiàn)在都知道Unicode至少都可以囊括幾億個字符)。除了對已經(jīng)定義的字符進(jìn)行統(tǒng)一外,Unicode聯(lián)盟與ISO工作組也同意今后任何的擴(kuò)展工作兩者均保持同步,因此雖然從歷史的意義上講Unicode與UCS不是一回事(甚至細(xì)節(jié)上說也不是一回事),但現(xiàn)在提起Unicode,指代兩者均無不妥,畢竟因為已經(jīng)統(tǒng)一了。

(現(xiàn)在網(wǎng)上基本上把Unicode字符集叫做UCS,Unicoide的全稱是 Universal Multiple-Octet Coded Character Set簡寫也是UCS,一看也對上了,害,只能說天注定)。

現(xiàn)在Unicode編碼點分為17個平面(plane),每個平面包含216(即65536)個碼位(codepoint)。17個平面的碼位可表示為從U+xx0000到U+xxFFFF,其中xx表示十六進(jìn)制值從0016到1016,共計17個平面。

這第一個位置(當(dāng)xx是00的時候)被稱為BMP(基本多文種平面,BasicMultilingualPlane)。它包含了最常用的碼位從U+0000到U+FFFF(常見的65536個字符)。

其余16個平面(從下面的1號平面到16號平面),你可以叫做非BMP,由此這樣分的話里面的字符就有兩個概念:BMP字符和非BMP字符,后者也被稱為補(bǔ)充字符。(偷偷告訴你們,大家喜聞樂見的Emoji表情都是在1號平面,范圍是U+1F600-U+1F64F)

萬字長文講解編碼知識,看這文就夠了!| 原力計劃

(2)UCS-2和UCS-4

ISO10646標(biāo)準(zhǔn)為“通用字符集”(UCS)定義了一種16位的編碼形式(即UCS-2)UCS-2全稱Universal Character Set coded in 2octets,從英文上就可以看出含義,以2字節(jié)編碼的通用字符集編碼,固定占用2個字節(jié),它包含65536個編碼空間(可以為全世界最常用的63K字符編碼,為了兼容Unicode,0xD800-0xDFFF之間的碼位未使用)。

例:“漢”的UCS-2編碼為6C49。除此之外ISO10646標(biāo)準(zhǔn)為“通用字符集”(UCS)還定義了一種31位的編碼形式(即UCS-4),UCS-4全稱UniversalCharacter Set coded in 4 octets,其編碼固定占用4個字節(jié),編碼空間為0x00000000 ~0x7FFFFFFF(可以編碼20多億個字符)。

隨著Unicode與ISO 10646合并統(tǒng)一,Unicode就用UCS通用字符集標(biāo)準(zhǔn),早期的 Unicode 編碼實現(xiàn)也就采用了UCS-2和UCS-4。(準(zhǔn)確來說是UCS-2,UCS-4基本上是理論,沒付諸實際,畢竟早期65536個字符已經(jīng)夠用了,我兩個字節(jié)編碼能實現(xiàn)的事,腦子笨的人才會用四個字節(jié)實現(xiàn),你以為存儲和帶寬有多的)。

萬字長文講解編碼知識,看這文就夠了!| 原力計劃

這里編碼最多也就存在UCS-2(big Endian和LittleEndian先不管,后面會講)。

Unicode字符集只規(guī)定了碼點和文字之間的對應(yīng)關(guān)系,并沒有規(guī)定碼點在計算機(jī)中如何存儲。UCS-2和UCS-4就規(guī)定了具體的實現(xiàn),后來改進(jìn)演變?yōu)榱薝TF-16, UTF-32。然后又創(chuàng)造了一種全新的簡單粗暴好用的變長編碼UTF-8,于是乎這三哥們就形成了現(xiàn)代Unicode字符集編碼實現(xiàn)的三劍客。

(3)UTF-16與UTF-32

Unicode與ISO 10646合并統(tǒng)一后,Unicode與 ISO 10646 的通用字符集概念(UCS)相對應(yīng)。早期實現(xiàn)Unicode用的編碼是UCS-2,后來隨著發(fā)展發(fā)現(xiàn) 216(即65536)個字符不能滿足了,Unicode標(biāo)準(zhǔn)本身發(fā)生了變化:65536個字符顯得不足,引入了更大的31位空間和一個編碼(UCS-4),每個字符需要4個字節(jié)。

但是統(tǒng)一碼聯(lián)盟對此予以抵制(這就是為什么我之前說UCS-4是一種理論編碼,根本就沒付諸實際),這是因為每個字符4個字節(jié)浪費了很多磁盤空間和內(nèi)存,并且因為一些制造商已經(jīng)在每個字符2個字節(jié)的技術(shù)上投入了大量資金。所以最后通過一系列巴拉巴拉討論規(guī)定形成了一種折衷方案,建立了UTF-16編碼方案(此時Unicode標(biāo)準(zhǔn)2.0),它替代了原有的UCS-2,并做了改進(jìn)。

它與UCS-2一樣,它使用兩個字節(jié)為全世界最常用的63K字符編碼,不同的是,它使用4個字節(jié)對不常用的字符進(jìn)行編碼。目的就是為了支持從17個平面編碼1,112,064個代碼點。

UTF-16屬于變長編碼。我們可以將UTF-16編碼看成是UCS-2編碼父集。在沒有輔助平面字符(surrogate code points)前,UTF-16與UCS-2所指的是同一意思。但當(dāng)引入輔助平面字符后,就稱為UTF-16了。

現(xiàn)在應(yīng)該認(rèn)為UCS-2已作廢,如果有人還用這種,也不必糾結(jié),它就是表達(dá)用定長2字節(jié)編碼,自己心里清楚就行(基本上你查維基百科上UCS-2都是重定向到UTF-16)。

另外當(dāng)時ISO 10646的UCS-4編碼并入了Unicode標(biāo)準(zhǔn),而UCS-4有20多億個編碼空間,但實際使用范圍并不超過0x10FFFF,并且為了兼容Unicode標(biāo)準(zhǔn),ISO也承諾將不會為超出0x10FFFF的UCS-4編碼賦值。

由此提出了實實在在的UTF-32編碼(現(xiàn)在也應(yīng)該認(rèn)為UCS-4像UCS-2一樣作廢,維基百科上UCS-4也重定向到UTF-32頁面),它的編碼值與UCS-4相同,只不過其編碼空間被限定在了0~0x10FFFF之間。因此也可以說:UTF-32是UCS-4的一個子集。

(現(xiàn)在若有軟件聲稱自己支持UCS-2,那其實是暗指它不能支持在UTF-16中超過2字節(jié)的字集。)

UTF-16(16 位 Unicode轉(zhuǎn)換格式)是一種字符編碼,能夠?qū)nicode的所有1,112,064個有效碼點進(jìn)行編碼(實際上,此代碼點數(shù)由UTF-16的設(shè)計決定,這個你細(xì)品你就知道什么意思,就好像某個班有55個人,根據(jù)55個座位確定55個人,而55個座位這個多少是由55個人決定的,兩者是相互的,這是一個哲學(xué)道理,hh扯遠(yuǎn)了,所以其中意味自行明白)。

前面提到過:Unicode編碼點分為17個平面(plane),每個平面包含216(即65536)個碼位(codepoint),而第一個平面稱為“基本多語言平面”(Basic Multilingual Plane,簡稱BMP),其余平面稱為“輔助平面”(Supplementary Planes)。其中“基本多語言平面”(00xFFFF)中0xD8000xDFFF之間的碼位作為保留,未使用。

UCS-2只能編碼“基本多語言平面”中的字符,此時UTF-16與UCS-2的編碼一樣(都直接使用Unicode的碼位作為編碼值),例:“漢”在Unicode中的碼位為6C49,而在UTF-16編碼也為6C49。

另外,UTF-16還可以利用保留下來的0xD800-0xDFFF區(qū)段的碼位來對“輔助平面”的字符的碼位進(jìn)行編碼,因此UTF-16可以為Unicode中所有的字符編碼。

UTF-16和UTF-32也就是如今Unicode編碼的標(biāo)準(zhǔn)之二,他們的區(qū)別就是UTF-16是變長編碼,大部分是2字節(jié)和少部分4字節(jié),UTF-32是定長編碼,表示任何字符都用 4 字節(jié)

在線客服 雙翌客服
客服電話
  • 0755-23712116
  • 13822267203