編碼方式的簡(jiǎn)介 1. ASCII ASCII是7比特的字符集,涵蓋了英語(yǔ)中的絕大多數(shù)字符。編碼從0到127. 2. ISOLatin-1(the ISO-8859-1 standard) ISO Latin-1是8比特的字符集,定義了256個(gè)字符。前128個(gè)字符(00000000-01111111)與ASCII完全一致。
3. Unicode Unicode只是定義了字符的編碼值,并未指定值以何種形式存儲(chǔ)。比如漢字“田”的Unicode編碼是7530,轉(zhuǎn)換為二進(jìn)制是01110101,00110000。比方現(xiàn)在定義一種unicode的實(shí)現(xiàn)方式UTF-FAKE,規(guī)則是 a. 使用24個(gè)字節(jié) b. 每個(gè)字節(jié)的高7位都是1 c. 每個(gè)字節(jié)的最末一位存儲(chǔ)unicode編碼值 那么01110101,00110000的存儲(chǔ)形式是 11111110, 11111110, 11111110, 11111110, 11111110, 11111110, 11111110, 11111110, 11111110, 11111111, 11111111, 11111111, 11111110, 11111111, 11111110, 11111111, 11111110, 11111110, 11111111, 11111111, 11111110, 11111110, 11111110, 11111110 其中末位為藍(lán)色0的字節(jié)為補(bǔ)足字節(jié)。 實(shí)際使用的編碼方式UTF-8使用三個(gè)字節(jié)存儲(chǔ)“田” 01110101,00110000,如下 11100111, 10010100, 10110000
Unicode的第一個(gè)版本于1991年發(fā)布,該版本允許的的最大編碼空間是兩個(gè)字節(jié)。96年發(fā)布的Unicode 2.0版本引入了surrogate pair,將Unicode的編碼數(shù)目擴(kuò)充到了百萬(wàn)級(jí),由于可見的將來(lái)該數(shù)目不大可能用光,因此Unicode委員會(huì)對(duì)外宣稱該上限永不會(huì)更改。Surrogate pair在UTF-16和UTF-32中得到了實(shí)現(xiàn)。Unicode的前256個(gè)字符及編碼值與Latin-1完全一致。比如大寫字母A在Latin-1和Unicode中的編碼值都是0x41(十進(jìn)制的65)。 Unicode的編碼值范圍是 000000hex 到10FFFFhex,可劃分為17個(gè)plane,每個(gè)plane包含65536(= 216)個(gè)字符。Plane的代碼從0到16(十進(jìn)制),對(duì)應(yīng)于 000000hex,010000hex,020000hex,… … ,0F0000hex,10FFFFhex的藍(lán)色部分。 Unicode的表示方式一般是”U ”后綴上4到6個(gè)十六進(jìn)制字符,如”田“的Unicode表示方式是U 7530。
4. UTF-8 UTF-8采用可變長(zhǎng)度的編碼,長(zhǎng)度從1到4個(gè)字節(jié)不等。某些應(yīng)用識(shí)別非標(biāo)準(zhǔn)的'utf8' 或'UTF 8'別名。只有ASCII字符在UTF-8中使用一個(gè)字節(jié)編碼,且值與ASCII完全相同,其余字符在UTF-8中使用2到4個(gè)字節(jié)。因此UTF-8中的單字節(jié)且只有單字節(jié)編碼字符的最高的1個(gè)比特是0。 UTF-8對(duì)Unicode字符的編碼規(guī)則如下
說(shuō)明如下: 1. 只有ASCII使用單字節(jié)編碼 2. Unicode編碼值大于127的字符使用多個(gè)字節(jié)編碼。多字節(jié)序列的第一個(gè)字節(jié)稱為leading byte,后續(xù)的字節(jié)稱為continuation bytes。Leading byte的高位是110,1110或11110,其中的“1”的個(gè)數(shù)標(biāo)明了序列中的字節(jié)總數(shù)。如2個(gè)字節(jié)序列的leading byte為 3. 單字節(jié)序列、leading bytes和continuationbytes的高位分別是0,110/1110/11110和10,因此不會(huì)混淆。 還是以漢字”田“為例,展示Unicode字符如何按照UTF-8存儲(chǔ)。”田“的Unicode值是U 7530,比對(duì)上表發(fā)現(xiàn)介于U 0800 - U FFFF之間,因此需要3個(gè)字節(jié)來(lái)存儲(chǔ)。7530轉(zhuǎn)為二進(jìn)制是1110101,00110000,一共15位。但由于UTF-8的3字節(jié)編碼存儲(chǔ)16個(gè)比特,因此將1110101,00110000的高一位補(bǔ)零變成16比特01110101,00110000。然后將這16比特依次填入三字節(jié)序列1110xxxx 10xxxxxx 10xxxxxx的x中,得到結(jié)果 11100111 10010100 10110000,寫成16進(jìn)制就是E7 94 B0 注意:雖然Unicode中的前256個(gè)字符及編碼值與Latin-1完全一致,但UTF-8只對(duì)前128個(gè)即ASCII字符采用單字節(jié)編碼,其余128個(gè)Latin-1字符是采用2個(gè)字節(jié)編碼。因此ASCII編碼的文件可以直接以UTF-8方式讀取,而Latin-1的文件若包含值為128-255的字符則不可以。 5. UTF-16 UTF-16也是采用可變長(zhǎng)度編碼,可以是一個(gè)或者兩個(gè)16比特。某些應(yīng)用中允許使用非標(biāo)準(zhǔn)的UTF_16或者UTF16作為別名。Unicode中的第一個(gè)plane的65536(= 216)codepoints采用16比特編碼,其余的16個(gè)plane均采用2個(gè)16比特編碼。采用2個(gè)16比特編碼的前后兩個(gè)16bit分別稱為lead surrogate pair和trail surrogate pair,之所以稱為surrogate是因?yàn)閱为?dú)一個(gè)16bit不代表任何字符,只有組合起來(lái)才有意義。 既然UTF-16也是可變長(zhǎng)度編碼,如何區(qū)分某個(gè)16bit是單獨(dú)表示一個(gè)字符還是與后續(xù)的16bit組合起來(lái)表示一個(gè)字符呢?Unicode將D800–DBFF和DC00–DFFF這兩個(gè)范圍作為保留區(qū)間,沒有將之分配給任何Unicode字符,若某16比特落在D800–DBFF范圍內(nèi),便可將之視為采用2個(gè)16bit編碼字符的第一個(gè)16bit,而落在DC00–DFFF的16bit可視為采用2個(gè)16bit編碼字符的第二個(gè)16bit。這就使得Unicode第一個(gè)plane實(shí)際可分配使用的code points只有65536 – (DFFF - D800 1) = 65536 – 8*256 = 63488。 采用一個(gè)16bit編碼的Unicode字符在UTF-16中的編碼值與其在Unicode中是相等的,比如英文大寫字母A的Unicode值是U 0041,其UTF-16編碼是0041 hex 。Unicode第二到第十七個(gè)plane采用兩個(gè)16bit即surrogate pairs的字符從其Unicode code point到UTF-16的轉(zhuǎn)換規(guī)則是 1. 范圍為0x10000 … 0x10FFFF的codepoint減去0x010000,減過(guò)后的結(jié)果范圍是0x00000到0xFFFFF,使得該結(jié)果可以使用5位16進(jìn)制亦即20位2進(jìn)制數(shù)表示 2. 結(jié)果中高10位(范圍是0x0到0x3FF)加上0xD800(結(jié)果范圍是0xD800到0xDBFF)作為雙16bit的第一個(gè)16bit即leadsurrogate 3. 結(jié)果中低10位(范圍是0x0到0x3FF)加上0xDC00(結(jié)果范圍是0xDC00到0xDFFF)作為雙16bit的第二個(gè)16bit即trailsurrogate
這樣UTF-16與UTF-8都是self-synchronizing的,即某個(gè)16bit是否是一個(gè)字符的開始無(wú)需檢查其前一個(gè)或者后一個(gè)16bit。與UTF-8的不同之處是,UTF-16不支持從某個(gè)隨機(jī)的字節(jié)開始讀取。 舉例:UTF-16 序列 0041, D801DC01 (字符'A BOM(byte-order mark) BOM是Unicode中用來(lái)標(biāo)識(shí)字節(jié)順序的字符。 對(duì)于UTF16和UTF32,由于編碼單元分別是16bit和32bit,即2個(gè)和4個(gè)字節(jié),編碼單元內(nèi)字節(jié)的順序就取決于計(jì)算機(jī)的體系結(jié)構(gòu)。以英文大寫字母A和漢字田為例,大端(big endianness,縮寫為BE)和小端(littleendianness,縮寫為L(zhǎng)E)存儲(chǔ)的字節(jié)序列是
BOM就是用來(lái)標(biāo)識(shí)編碼使用的是大端還是小端存儲(chǔ),該符號(hào)位于文本序列起始字節(jié)之前。
UTF-8 UTF-8中的BOM是 0xEF,0xBB,0xBF。Unicode標(biāo)準(zhǔn)里面允許UTF-8使用BOM,但并不要求也不鼓勵(lì)使用。由于UTF8編碼單位是字節(jié),字節(jié)的先后順序在編碼、傳輸和解碼過(guò)程中均不改變,因此不存在endianness。BOM在UTF8中的唯一作用是標(biāo)識(shí)序列使用的是UTF8編碼,在由其它使用BOM的編碼轉(zhuǎn)換為UTF8編碼的情況下,建議在UTF8序列中保留BOM以便轉(zhuǎn)換回原編碼的時(shí)候不丟失BOM信息。
接下來(lái)看看用Notepad 的HEX-Editor插件查看的文件16進(jìn)制的編碼。 文件中僅包含一個(gè)英文大寫字母A,其Unicode編碼值是U 0041。 使用UTF-8(缺省包含BOM),字節(jié)序列是ef bb bf 41
使用不帶BOM的UTF-8,字節(jié)序列是 41。
UTF-16UTF-16中bigendianness和littleendianness的BOM分別是U FEFF和U FFFE??梢允褂镁幋a方式UTF-16BE和UTF-16LE來(lái)顯式地標(biāo)明字節(jié)順序,當(dāng)使用了UTF-16BE和UTF-16LE時(shí),BOM不應(yīng)該再出現(xiàn)在字節(jié)序列中,很多應(yīng)用直接忽略該字符若其仍然存在。 由于Notepad 不支持UTF16編碼,因此下面的截圖中使用了UTF-16的前身UCS-2來(lái)替代。UCS-2對(duì)Unicode的第一個(gè)plane的編碼與UTF-16相同,都是1個(gè)16bit,且編碼結(jié)果相同。
UTF-32 UTF32中的bigendianness和littleendianness的BOM分別是0000FEFF和FFFE0000。 總結(jié)五種編碼方式的BOM依次是
|
|
來(lái)自: liang1234_ > 《關(guān)于編碼》