欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

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

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

開(kāi)通VIP
Unicode編碼及其實(shí)現:UTF-16、UTF-8,and more

田海立@CSDN

2012-04-25


本文主要討論Unicode的編碼及其各種實(shí)現,著(zhù)重討論UTF-16,UTF-8的實(shí)現規則,以及Big-endian和Little-Endian的存儲順序。


一、Unicode編碼


        Unicode出現之前已經(jīng)有各種編碼標準:ANSI、ISO8859-1、GB2312、GBK以及BIG-5等。Unicode試圖統一各種編碼,在Unicode演進(jìn)過(guò)程中,也有自身不斷修復的過(guò)程:剛開(kāi)始的時(shí)候用16位表達65535個(gè)字符,認為已經(jīng)足夠收集所有的字符;后來(lái)隨著(zhù)大量中文、韓文和日文等表意文字的加入,已經(jīng)超出了65535個(gè)字符,16位已經(jīng)不能描述所有的字符集了。

        在Unicode字符集中的某個(gè)字符對應的代碼值,稱(chēng)作代碼點(diǎn)(Code Point),用16進(jìn)制書(shū)寫(xiě),并加上U+前綴。比如,‘田’的代碼點(diǎn)是U+7530;‘A’的代碼點(diǎn)是U+0041。

        Unicode定義的字符集已經(jīng)超過(guò)16位所能表達的范圍,把所有這些CodePoint分成17個(gè)代碼平面(Code Plane)

  • U+0000 ~ U+FFFF劃入基本多語(yǔ)言平面(Basic MultilingualPlane,簡(jiǎn)記為BMP);
  • 其余劃入16個(gè)輔助平面(Supplementary Plane),代碼點(diǎn)范圍U+10000 ~ U+10FFFF。

        雖然這樣劃分,但并不是每個(gè)Plane中的Code point都對應有字符,這里面有保留的,還有特殊用途的。


二、Unicode編碼的實(shí)現


        Unicode的實(shí)現方式不同于編碼方式。一個(gè)字符的Unicode編碼是確定的,但是在實(shí)際存儲和傳輸過(guò)程中,由于不同系統平臺的設計不一定一致,以及出于節省空間的目的,對Unicode編碼的實(shí)現方式有所不同。Unicode的實(shí)現方式稱(chēng)為Unicode轉換格式(Unicode Transformation Format,簡(jiǎn)稱(chēng)為UTF)。

        對Unicode編碼的主要有UTF-16BE、UTF-16LE、UTF-8、UTF-7以及UTF-32等實(shí)現方式,目前常用的實(shí)現方式是UTF-16LE、UTF-16BE和UTF-8。


2.1 UTF-16

        UTF-16是用16bit編碼來(lái)表達Unicode,這樣表達范圍是216(即65536),也就是UTF-16的代碼單元(Code Unit)為16bits。如果表達BMP內的字符,用一個(gè)UTF-16的Code Unit就可表達,對于輔助平面內的字符,UTF-16有巧妙的設計。

        落在BMP內,從U+D800U+DFFF之間的Code Point區段是永久保留不映射到字符, UTF-16利用這保留下來(lái)的0xD800-0xDFFF區段的CodePoint來(lái)對輔助平面內的字符的Code Point進(jìn)行編碼。


對U+0000.. U+D7FF以及U+E000.. U+FFFF的編碼

        UTF-16與UCS-2對這個(gè)范圍內的CodePoint進(jìn)行編碼,采用單個(gè)16bit長(cháng)的CodeUnit,數值等價(jià)于對應的Code Point。BMP中的這些Code Point是僅有的可以被UCS-2表示的Code Point。

對U+10000.. U+10FFFF的編碼

        輔助平面(Supplementary Planes)中的CodePoint,在UTF-16中被編碼為一對16bit長(cháng)的Code Unit(即32bit,4Bytes),稱(chēng)作代理對(surrogate pair)。


 具體方法是:

UTF-16解碼

hi \ lo

DC00

DC01

   …   

DFFF

D800

10000

10001

103FF

D801

10400

10401

107FF

  

DBFF

10FC00

10FC01

10FFFF

  1. Code Point減去0x10000, 得到的值是長(cháng)度為20bit(0..0xFFFFF);
  2. 步驟1得到數值的高位的10比特的值(值范圍為0..0x3FF)被加上0xD800得到第一個(gè)Code Unit或稱(chēng)作高位代理(high surrogate)或前導代理(lead surrogate)。取值范圍是0xD800..0xDBFF。
  3. 步驟1得到數值的低位的10比特的值(值范圍為0..0x3FF)被加上0xDC00得到第二個(gè)Code Unit或稱(chēng)作低位代理(low surrogate)或后尾代理(trail surrogate)。取值范圍是0xDC00..0xDFFF。

        這樣,這個(gè)范圍內的字符就被編碼成了一個(gè)代理對[lead surrogate,trail surrogate]:兩個(gè)16bits的Code Unit,取值范圍分別是0xD800..0xDBFF和0xDC00..0xDFFF。而B(niǎo)MP中得到的Code Unit的范圍是0x0000..0xFFFF(0xD800..0xDFFF是保留的,不包含其中),所以這三個(gè)區段是相互不重疊的,在解碼時(shí)很容易實(shí)現。

        UTF-16解碼[高位代理+低位代理]得到的Code Unit對與Code Point的對應關(guān)系如上表所示。


        下面以對U+64321的UTF-16編碼為例,看一下對于輔助平面內的字符是如何編碼的:

V  = 0x64321

Vx = V - 0x10000

     = 0x54321

     = 01010100 0011 0010 0001

 

Vh = 01 0101 0000 // Vx 的高位部份的 10 bits

Vl  = 11 0010 0001 // Vx 的低位部份的 10 bits

w1 = 0xD800           // 結果的前16位元初始值

w2 = 0xDC00          // 結果的后16位元初始值

 

w1 = w1 | Vh

   = 1101 1000 0000 0000

     |             01 0101 0000

   = 1101 1001 0101 0000

   = 0xD950

 

w2 = w2 | Vl

   = 1101 1100 0000 0000

    |              11 0010 0001

   = 1101 1111 0010 0001

   = 0xDF21


        所以,這個(gè)字 U+64321 最終的 UTF-16 編碼是:

0xD950 0xDF21


        UTF-16的Code Unit是16bits,兩個(gè)字節。存儲一個(gè)Code Unit的時(shí)候,還有存取的先后順序問(wèn)題,也就是Endian問(wèn)題,這在后面章節講述。


2.2 UTF-8

        UTF-8(8-bit Unicode Transformation Format)是一種針對Unicode的可變長(cháng)度字符編碼,使用一至四個(gè)字節為每個(gè)字符編碼:

  •  Unicode范圍為U+0000..U+007F 的128個(gè)ASCII字符只需一個(gè)字節編碼;
  •  Unicode范圍為U+0080..U+07FF的字符需要二個(gè)字節編碼;
  •  Unicode范圍為U+0800..U+FFFF的其他BMP中的字符(這包含了大部分常用字)使用三個(gè)字節編碼;
  •  Unicode 輔助平面的字符(其他極少使用的字符)使用四字節編碼。

        對上述提及的第四種字符而言,UTF-8使用四個(gè)字節來(lái)編碼似乎太耗費資源了。但UTF-8對所有常用的字符都只用三個(gè)字節表達,而且UTF-16編碼對前述的第四種字符同樣需要四個(gè)字節來(lái)編碼,而如果是ASCII居多的字符,UTF-8能極大的節約存儲空間。UTF-8逐漸成為電子郵件、網(wǎng)頁(yè)及其他儲存或傳送文字的應用中,優(yōu)先采用的編碼?;ヂ?lián)網(wǎng)工程工作小組(IETF)要求所有互聯(lián)網(wǎng)協(xié)議都必須支持UTF-8編碼?;ヂ?lián)網(wǎng)郵件聯(lián)盟(IMC)建議所有電子郵件軟件都支持UTF-8編碼。


        對CodePoint各個(gè)范圍內的字符進(jìn)行UTF-8編碼的規則如下:

Code point

UTF-8字節流

U+00000000 – U+0000007F

0xxxxxxx

U+00000080 – U+000007FF

110xxxxx 10xxxxxx

U+00000800 – U+0000FFFF

1110xxxx 10xxxxxx 10xxxxxx

U+00010000 – U+001FFFFF

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

其中,U+D800到U+DFFF之間的區段在Unicode字符集的定義中沒(méi)有具體字符使用的,被用來(lái)在UTF-16編碼中對輔助平面的字符進(jìn)行編碼。


        下面以“田”(Code Point為U+7530)為例,看如何對其進(jìn)行UTF-8編碼:

  •  U+7530落在U+0800..U+FFFF區間,采用三字節編碼;
  •  0x7530轉換為二進(jìn)制為111 010100 110000;
  •  代入表中,得到111001111001010010110000;

        這樣,得到“田”(U+7530)的UTF-8編碼:0xE7 94 B0。


        知道UTF-8的編碼規則,我們可以對于UTF-8編碼中的任意字節B,進(jìn)行下面解碼:

  •  如果B的第一位為0,則B為ASCII碼,并且B獨立的表示一個(gè)字符;如果B的第一位為1,第二位為0,則B為一個(gè)非ASCII字符(該字符由多個(gè)字節表示)中的一個(gè)字節,并且不為字符的第一個(gè)字節編碼(字符的第一個(gè)字節之外的后編碼);
  •  如果B的前兩位為1,第三位為0,則B為一個(gè)非ASCII字符(該字符由多個(gè)字節表示)中的第一個(gè)字節,并且該字符由兩個(gè)字節表示;
  •  如果B的前三位為1,第四位為0,則B為一個(gè)非ASCII字符(該字符由多個(gè)字節表示)中的第一個(gè)字節,并且該字符由三個(gè)字節表示;
  •  如果B的前四位為1,第五位為0,則B為一個(gè)非ASCII字符(該字符由多個(gè)字節表示)中的第一個(gè)字節,并且該字符由四個(gè)字節表示。

 

2.3 UCS-2 vs UTF-16,UCS-4 vs UTF-32

        UCS-2每個(gè)字符占用2個(gè)字節。UCS-2是UTF-16的子集。在沒(méi)有輔助平面前,UTF-16與UCS-2所指的是同一的意思。但當引入輔助平面字符后,UTF-16加入了對輔助平面內的字符的支持?,F在若有軟件聲稱(chēng)自己支持UCS-2編碼,那其實(shí)是暗指它不支持UTF-16中超過(guò)2bytes的字集。亦即,對于小于0x10000的UCS碼,UTF-16編碼就等于UCS碼。Java早期版本對Unicode的支持,就只是UCS-2的支持,現在加入了對UTF-16的完整支持。

 

        UCS-4UTF-32的意義一致,對每個(gè)字符都使用4字節(31位字符集,加上恒為0的首位,共需占據32位)。理論上最多能表示231個(gè)字符,完全可以涵蓋一切語(yǔ)言所用的符號。雖然每一個(gè)Code Point使用固定長(cháng)定的字節看似方便,對于普通只需要2個(gè)字節存儲的常用字占絕大對數的字符集來(lái)說(shuō),卻極大的浪費了空間,并沒(méi)怎么得到應用。


三、Big-Endian/Little-Endian與BOM

        在講UTF-16編碼方式時(shí)說(shuō)到,UTF-16編碼的Code Unit是2個(gè)字節,這兩個(gè)字節在傳輸和存儲過(guò)程中,高/低位位置不同,是不同的字符。比如,“田”的UTF-16編碼是0x7530,但是如果存成0x3075,就變成了“ふ”,成了另外的字符。

        所以,為了識別一個(gè)編碼過(guò)的字符的存儲順序,必須用特殊字符來(lái)指示。Unicode字符中U+FEFF被用來(lái)指示這種存儲順序,被稱(chēng)作Byte Order Mark(BOM)。

  •  Big-Endian:最低位地址存放高位字節,可稱(chēng)高位優(yōu)先,內存從最低地址開(kāi)始按順序存放(高數位數字先寫(xiě))。最高位字節放最前面。
  •  Little Endian:最低位地址存放低位字節,可稱(chēng)低位優(yōu)先,內存從最低地址開(kāi)始按順序存放(低數位數字先寫(xiě))。最低位字節放最前面。

        BOM在Big-Endian系統上存儲為FE FF;而在Big-Endian系統上存儲則為FF FE。所以在以Big-Endian存儲的UTF-16(UTF-16BE)的文件的開(kāi)頭,用FEFF指示;以L(fǎng)ittle-Endian存儲的UTF-16(UTF-16LE)的文件的開(kāi)頭,用FFFE指示。

        BOM的UTF-8編碼為11101111 1011101110111111 (EF BB BF),所以一般EF BB BF被放在文本的開(kāi)頭,用來(lái)指示其編碼為UTF-8。

        

四、Unicode編碼實(shí)踐


        在Windows的文本編輯工具記事本上,選擇“另存為”的時(shí)候,用戶(hù)可以選擇不同的編碼選項,對應編碼選項有“ANSI”,“Unicode”,“Unicode big endian”,以及“UTF-8”。因為Windows的存儲方式是Little-Endian,所以“Unicode”,“Unicode big endian”對應的分別是UTF-16LE和UTF-16BE。

       

        讀者可以試著(zhù)編寫(xiě)一串字符,然后分別用不同的編碼保存,再用可以16進(jìn)制編寫(xiě)的純文本編輯工具(如,Ultra-edit)來(lái)檢驗一下具體的編碼實(shí)現和存儲順序。下面是筆者將“田海立(U+7530, U+6D77, U+7ACB)”以不同編碼方式保存,得到的結果:

田海立_UTF-16BE.txt

        FEFF75306D777ACB

田海立_UTF-16LE.txt

        FFFE3075776DCB7A

田海立_UTF-8.txt

        EFBBBFE794B0E6B5B7E7AB8B

        為了明確起見(jiàn),BOM的編碼用粗體標注;田的編碼用紅色標注;海的編碼用綠色標注;立的編碼用藍色標注??梢钥吹?,記事本(Notepad)存儲的Unicode編碼的文件的開(kāi)頭位置,用BOM的相應編碼指示了編碼格式。


【后記】歷史

        最近需要用到Unicode的編碼實(shí)現方式,又收集了一下資料。發(fā)現早在06年的時(shí)候,筆者就準備總結一下Unicode的編碼實(shí)現,文檔里也已經(jīng)有了提綱?,F在也不記得當時(shí)什么原因給耽擱了,好在現在及時(shí)總計歸納。好腦子不如爛筆頭啊。如果當初總結下來(lái),現在也不用再浪費時(shí)間收集資料。

        希望,這次的總結能比較完善,以后再用到Unicode編碼,只要參考此文即可?。ó斎磺疤崾荱nicode標準別又演進(jìn)了^_^)


【附】基本概念對照

  1. Code Point代碼點(diǎn)或碼位
  2. Code Unit代碼單元或碼元,是指一個(gè)已編碼的文本中具有最短的比特組合的單元。對于UTF-8來(lái)說(shuō),碼元是8比特長(cháng);對于UTF-16來(lái)說(shuō),碼元是16比特長(cháng);對于UTF-32來(lái)說(shuō),碼元是32比特長(cháng)。
  3. BMP - Basic Multilingual Plane
  4. UTF - Unicode Transformation Format
  5. BOM – Byte Order Mark
  6. UCS - Universal Character Set
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
UNICODE
談?wù)刄nicode編碼,簡(jiǎn)要解釋UCS、UTF、BMP、BOM等名詞
unicode、ucs-2、ucs-4、utf-16、utf-32、utf-8 - 歷史的...
編碼匯總整理
UTF-8 GBK UTF8 GB2312 之間的區別和關(guān)系 | 前端設計交流 - Ded...
編碼又見(jiàn)編碼
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久