国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - 編程技術(shù) - 程序員趣味讀物 談?wù)刄nicode編碼

程序員趣味讀物 談?wù)刄nicode編碼

2020-07-23 13:43編程貓 編程技術(shù)

這是一篇程序員寫給程序員的趣味讀物。所謂趣味是指可以比較輕松地了解一些原來不清楚的概念,增進(jìn)知識(shí),類似于打RPG游戲的升級(jí)。整理這篇文章的動(dòng)機(jī)是兩個(gè)問題

問題一:

  使用Windows記事本的“另存為”,可以在GBK、Unicode、Unicode big endian和UTF-8這幾種編碼方式間相互轉(zhuǎn)換。同樣是txt文件,Windows是怎樣識(shí)別編碼方式的呢?

  我很早前就發(fā)現(xiàn)Unicode、Unicode big endian和UTF-8編碼的txt文件的開頭會(huì)多出幾個(gè)字節(jié),分別是FF、FE(Unicode),FE、FF(Unicode big endian),EF、BB、BF(UTF-8)。但這些標(biāo)記是基于什么標(biāo)準(zhǔn)呢?

  問題二:

  最近在網(wǎng)上看到一個(gè)ConvertUTF.c,實(shí)現(xiàn)了UTF-32、UTF-16和UTF-8這三種編碼方式的相互轉(zhuǎn)換。對(duì)于Unicode(UCS2)、GBK、UTF-8這些編碼方式,我原來就了解。但這個(gè)程序讓我有些糊涂,想不起來UTF-16和UCS2有什么關(guān)系。

  查了查相關(guān)資料,總算將這些問題弄清楚了,順帶也了解了一些Unicode的細(xì)節(jié)。寫成一篇文章,送給有過類似疑問的朋友。本文在寫作時(shí)盡量做到通俗易懂,但要求讀者知道什么是字節(jié),什么是十六進(jìn)制。

0、big endian和little endian

  big endian和little endian是CPU處理多字節(jié)數(shù)的不同方式。例如“漢”字的Unicode編碼是6C49。那么寫到文件里時(shí),究竟是將6C寫在前面,還是將49寫在前面?如果將6C寫在前面,就是big endian。還是將49寫在前面,就是little endian。

  “endian”這個(gè)詞出自《格列佛游記》。小人國的內(nèi)戰(zhàn)就源于吃雞蛋時(shí)是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開,由此曾發(fā)生過六次叛亂,其中一個(gè)皇帝送了命,另一個(gè)丟了王位。

  我們一般將endian翻譯成“字節(jié)序”,將big endian和little endian稱作“大尾”和“小尾”。

1、字符編碼、內(nèi)碼,順帶介紹漢字編碼

  字符必須編碼后才能被計(jì)算機(jī)處理。計(jì)算機(jī)使用的缺省編碼方式就是計(jì)算機(jī)的內(nèi)碼。早期的計(jì)算機(jī)使用7位的ASCII編碼,為了處理漢字,程序員設(shè)計(jì)了用于簡體中文的GB2312和用于繁體中文的big5。

  GB2312(1980年)一共收錄了7445個(gè)字符,包括6763個(gè)漢字和682個(gè)其它符號(hào)。漢字區(qū)的內(nèi)碼范圍高字節(jié)從B0-F7,低字節(jié)從A1-FE,占用的碼位是72*94=6768。其中有5個(gè)空位是D7FA-D7FE。

  GB2312支持的漢字太少。1995年的漢字?jǐn)U展規(guī)范GBK1.0收錄了21886個(gè)符號(hào),它分為漢字區(qū)和圖形符號(hào)區(qū)。漢字區(qū)包括21003個(gè)字符。2000年的GB18030是取代GBK1.0的正式國家標(biāo)準(zhǔn)。該標(biāo)準(zhǔn)收錄了27484個(gè)漢字,同時(shí)還收錄了藏文、蒙文、維吾爾文等主要的少數(shù)民族文字。現(xiàn)在的PC平臺(tái)必須支持GB18030,對(duì)嵌入式產(chǎn)品暫不作要求。所以手機(jī)、MP3一般只支持GB2312。

  從ASCII、GB2312、GBK到GB18030,這些編碼方法是向下兼容的,即同一個(gè)字符在這些方案中總是有相同的編碼,后面的標(biāo)準(zhǔn)支持更多的字符。在這些編碼中,英文和中文可以統(tǒng)一地處理。區(qū)分中文編碼的方法是高字節(jié)的最高位不為0。按照程序員的稱呼,GB2312、GBK到GB18030都屬于雙字節(jié)字符集 (DBCS)。

  有的中文Windows的缺省內(nèi)碼還是GBK,可以通過GB18030升級(jí)包升級(jí)到GB18030。不過GB18030相對(duì)GBK增加的字符,普通人是很難用到的,通常我們還是用GBK指代中文Windows內(nèi)碼。

  這里還有一些細(xì)節(jié):

  GB2312的原文還是區(qū)位碼,從區(qū)位碼到內(nèi)碼,需要在高字節(jié)和低字節(jié)上分別加上A0。

  在DBCS中,GB內(nèi)碼的存儲(chǔ)格式始終是big endian,即高位在前。

  GB2312的兩個(gè)字節(jié)的最高位都是1。但符合這個(gè)條件的碼位只有128*128=16384個(gè)。所以GBK和GB18030的低字節(jié)最高位都可能不是1。不過這不影響DBCS字符流的解析:在讀取DBCS字符流時(shí),只要遇到高位為1的字節(jié),就可以將下兩個(gè)字節(jié)作為一個(gè)雙字節(jié)編碼,而不用管低字節(jié)的高位是什么。

2、Unicode、UCS和UTF

  前面提到從ASCII、GB2312、GBK到GB18030的編碼方法是向下兼容的。而Unicode只與ASCII兼容(更準(zhǔn)確地說,是與ISO-8859-1兼容),與GB碼不兼容。例如“漢”字的Unicode編碼是6C49,而GB碼是BABA。

  Unicode也是一種字符編碼方法,不過它是由國際組織設(shè)計(jì),可以容納全世界所有語言文字的編碼方案。Unicode的學(xué)名是"Universal Multiple-Octet Coded Character Set",簡稱為UCS。UCS可以看作是"Unicode Character Set"的縮寫。

  根據(jù)維基百科全書(http://zh.wikipedia.org/wiki/)的記載:歷史上存在兩個(gè)試圖獨(dú)立設(shè)計(jì)Unicode的組織,即國際標(biāo)準(zhǔn)化組織(ISO)和一個(gè)軟件制造商的協(xié)會(huì)(unicode.org)。ISO開發(fā)了ISO 10646項(xiàng)目,Unicode協(xié)會(huì)開發(fā)了Unicode項(xiàng)目。

  在1991年前后,雙方都認(rèn)識(shí)到世界不需要兩個(gè)不兼容的字符集。于是它們開始合并雙方的工作成果,并為創(chuàng)立一個(gè)單一編碼表而協(xié)同工作。從Unicode2.0開始,Unicode項(xiàng)目采用了與ISO 10646-1相同的字庫和字碼。

  目前兩個(gè)項(xiàng)目仍都存在,并獨(dú)立地公布各自的標(biāo)準(zhǔn)。Unicode協(xié)會(huì)現(xiàn)在的最新版本是2005年的Unicode 4.1.0。ISO的最新標(biāo)準(zhǔn)是10646-3:2003。

  UCS規(guī)定了怎么用多個(gè)字節(jié)表示各種文字。怎樣傳輸這些編碼,是由UTF(UCS Transformation Format)規(guī)范規(guī)定的,常見的UTF規(guī)范包括UTF-8、UTF-7、UTF-16。

  IETF的RFC2781和RFC3629以RFC的一貫風(fēng)格,清晰、明快又不失嚴(yán)謹(jǐn)?shù)孛枋隽薝TF-16和UTF-8的編碼方法。我總是記不得IETF是Internet Engineering Task Force的縮寫。但I(xiàn)ETF負(fù)責(zé)維護(hù)的RFC是Internet上一切規(guī)范的基礎(chǔ)。

3、UCS-2、UCS-4、BMP

  UCS有兩種格式:UCS-2和UCS-4。顧名思義,UCS-2就是用兩個(gè)字節(jié)編碼,UCS-4就是用4個(gè)字節(jié)(實(shí)際上只用了31位,最高位必須為0)編碼。下面讓我們做一些簡單的數(shù)學(xué)游戲:

  UCS-2有2^16=65536個(gè)碼位,UCS-4有2^31=2147483648個(gè)碼位。

  UCS-4根據(jù)最高位為0的最高字節(jié)分成2^7=128個(gè)group。每個(gè)group再根據(jù)次高字節(jié)分為256個(gè)plane。每個(gè)plane根據(jù)第3個(gè)字節(jié)分為256行 (rows),每行包含256個(gè)cells。當(dāng)然同一行的cells只是最后一個(gè)字節(jié)不同,其余都相同。

  group 0的plane 0被稱作Basic Multilingual Plane, 即BMP?;蛘哒fUCS-4中,高兩個(gè)字節(jié)為0的碼位被稱作BMP。

  將UCS-4的BMP去掉前面的兩個(gè)零字節(jié)就得到了UCS-2。在UCS-2的兩個(gè)字節(jié)前加上兩個(gè)零字節(jié),就得到了UCS-4的BMP。而目前的UCS-4規(guī)范中還沒有任何字符被分配在BMP之外。

4、UTF編碼

  UTF-8就是以8位為單元對(duì)UCS進(jìn)行編碼。從UCS-2到UTF-8的編碼方式如下:

 

 

UCS-2編碼(16進(jìn)制)

UTF-8 字節(jié)流(二進(jìn)制)

0000 - 007F

0xxxxxxx

0080 - 07FF

110xxxxx 10xxxxxx

0800 - FFFF

1110xxxx 10xxxxxx 10xxxxxx

 

 

  例如“漢”字的Unicode編碼是6C49。6C49在0800-FFFF之間,所以肯定要用3字節(jié)模板了:1110xxxx 10xxxxxx 10xxxxxx。將6C49寫成二進(jìn)制是:0110 110001 001001, 用這個(gè)比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89。

  讀者可以用記事本測試一下我們的編碼是否正確。

  UTF-16以16位為單元對(duì)UCS進(jìn)行編碼。對(duì)于小于0x10000的UCS碼,UTF-16編碼就等于UCS碼對(duì)應(yīng)的16位無符號(hào)整數(shù)。對(duì)于不小于0x10000的UCS碼,定義了一個(gè)算法。不過由于實(shí)際使用的UCS2,或者UCS4的BMP必然小于0x10000,所以就目前而言,可以認(rèn)為UTF-16和UCS-2基本相同。但UCS-2只是一個(gè)編碼方案,UTF-16卻要用于實(shí)際的傳輸,所以就不得不考慮字節(jié)序的問題。

5、UTF的字節(jié)序和BOM

  UTF-8以字節(jié)為編碼單元,沒有字節(jié)序的問題。UTF-16以兩個(gè)字節(jié)為編碼單元,在解釋一個(gè)UTF-16文本前,首先要弄清楚每個(gè)編碼單元的字節(jié)序。例如收到一個(gè)“奎”的Unicode編碼是594E,“乙”的Unicode編碼是4E59。如果我們收到UTF-16字節(jié)流“594E”,那么這是“奎”還是“乙”?

  Unicode規(guī)范中推薦的標(biāo)記字節(jié)順序的方法是BOM。BOM不是“Bill Of Material”的BOM表,而是Byte Order Mark。BOM是一個(gè)有點(diǎn)小聰明的想法:

  在UCS編碼中有一個(gè)叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的編碼是FEFF。而FFFE在UCS中是不存在的字符,所以不應(yīng)該出現(xiàn)在實(shí)際傳輸中。UCS規(guī)范建議我們?cè)趥鬏斪止?jié)流前,先傳輸字符"ZERO WIDTH NO-BREAK SPACE"。

  這樣如果接收者收到FEFF,就表明這個(gè)字節(jié)流是Big-Endian的;如果收到FFFE,就表明這個(gè)字節(jié)流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK SPACE"又被稱作BOM。

  UTF-8不需要BOM來表明字節(jié)順序,但可以用BOM來表明編碼方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF(讀者可以用我們前面介紹的編碼方法驗(yàn)證一下)。所以如果接收者收到以EF BB BF開頭的字節(jié)流,就知道這是UTF-8編碼了。

  Windows就是使用BOM來標(biāo)記文本文件的編碼方式的。

6、進(jìn)一步的參考資料

  本文主要參考的資料是 "Short overview of ISO-IEC 10646 and Unicode" (http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html)。

  我還找了兩篇看上去不錯(cuò)的資料,不過因?yàn)槲议_始的疑問都找到了答案,所以就沒有看:

"Understanding Unicode A general introduction to the Unicode Standard" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter04a)
"Character set encoding basics Understanding character set encodings and legacy encodings" (http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&item_id=IWS-Chapter03)

  我寫過UTF-8、UCS-2、GBK相互轉(zhuǎn)換的軟件包,包括使用Windows API和不使用Windows API的版本。以后有時(shí)間的話,我會(huì)整理一下放到我的個(gè)人主頁上(http://fmddlmyy.home4u.china.com/)。

  我是想清楚所有問題后才開始寫這篇文章的,原以為一會(huì)兒就能寫好。沒想到考慮措辭和查證細(xì)節(jié)花費(fèi)了很長時(shí)間,竟然從下午1:30寫到9:00。希望有讀者能從中受益。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 中文字幕乱码一区二区三区 | 国产黄色av网站 | 精品96久久久久久中文字幕无 | 色国产精品| 亚洲国产成人av好男人在线观看 | 偷拍呻吟高潮91 | 成人av免费在线播放 | 国产大片在线观看 | 日韩成人av在线 | 色九色| 精品福利一区二区三区免费视频 | 特污影院| 少妇精品久久久久久久久久 | 国产成人综合在线观看 | 免费的av网站 | 少妇一级淫免费放 | 午夜精品久久久久 | 欧美一级在线观看 | 亚洲精品久久久久999中文字幕 | 久久久久久久免费观看 | 国产精品一二 | 国产三级| 久久av一区| 欧美一区二区三区在线观看视频 | 免费毛片视频 | 亚洲精品久久久久久一区二区 | 国产视频aaa | 欧美中文字幕一区 | 欧美视频精品 | 在线免费观看av电影 | 久久久免费视频播放 | 亚洲 在线 | 亚洲一区二区三区免费视频 | 日韩在线中文字幕 | 2024国产精品 | 男女视频在线 | 久久国产精品99久久久久久老狼 | 国产精品久久久久久久久晋中 | 精品无码久久久久国产 | 51ⅴ精品国产91久久久久久 | 99伊人网 |