成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

字符編碼(一)

UnixAgain / 2880人閱讀

摘要:最近在看書的時(shí)候突然糾結(jié)于相關(guān)字符編碼,查了一些資料,并寫了這篇文章,順帶做下筆記,希望能幫到一些人。解決傳統(tǒng)的字符編碼方案的局限。

最近在看書的時(shí)候突然糾結(jié)于Unicode相關(guān)字符編碼,查了一些資料,并寫了這篇文章,順帶做下筆記,希望能幫到一些人。文章如果有寫的不妥的或者不正確的地方還請大家糾正。

Unicode 編碼

Unicode是一個符號集,它對世界上大部分的文字系統(tǒng)進(jìn)行了整理、編碼,使得電腦可以用更為簡單的方式來呈現(xiàn)和處理文字。解決傳統(tǒng)的字符編碼方案的局限。

歷史上存在兩個獨(dú)立的嘗試創(chuàng)立單一字符集的組織,即國際標(biāo)準(zhǔn)化組織(ISO)和非營利機(jī)構(gòu)統(tǒng)一碼聯(lián)盟。前者開發(fā)的 ISO/IEC 10646 項(xiàng)目,后者開發(fā)的統(tǒng)一碼項(xiàng)目。因此最初制定了不同的標(biāo)準(zhǔn)。他們不久便發(fā)現(xiàn)對方的存在,大家為著相同的目的而工作,最后他們合并雙方的工作成果。統(tǒng)一碼(Unicode)的編碼方式與ISO 10646的通用字符集(Universal Character Set, 簡稱UCS)概念相對應(yīng)。

統(tǒng)一碼的編碼方式使用16位編碼空間,也就是每個字符占用2個字節(jié),最多可表示2^(16)個字符,基本滿足各種語言的需求,且實(shí)際上16為編碼空間并未完全使用,其中保留了大量空間作為未來備用。這里所說的16位編碼空間即統(tǒng)一碼的0號平面(也稱“基本多文種平面”,Basic Multilingual Plane,簡稱BMP),目前統(tǒng)一碼版本中另外定義了16個輔助平面,這樣就需求21位編碼空間,即 16+5 位,一共17個平面(不局限于),每個平面擁有2^(16)個代碼點(diǎn)。如下表所示(摘自Wikipedia):

ASCII

ASCII(“阿斯柯”) 是國際上普遍采用的一種字符編碼系統(tǒng),由8位二進(jìn)制進(jìn)行編碼,最高位恒為0,因此可以定義128個字符,其中包括10個十進(jìn)制數(shù)字、52個英文大小寫字母(A~Z, a~z)等。

UTF-8

UTF(Unicode Transformation Format, Unicode字符集轉(zhuǎn)換格式),UTF-7、UTF-8、UTF-16、UTF-32、GB18030...只是Unicode的一種實(shí)現(xiàn)方式,即怎樣將 Unicode 定義的數(shù)字轉(zhuǎn)換成程序數(shù)據(jù)。

UTF-8 編碼,以8位無符號整數(shù)為單位進(jìn)行編碼,是針對Unicode的可變長字符編碼,UTF-8 是 ASCII 編碼的父集,也就是說,UTF-8 與 ASCII 編碼兼容,如:對于0x000000-0x00007F之間的字符,即前128個字符,UTF-8 編碼與 ASCII 編碼完全相同。這使得原來處理 ASCII 碼字符的軟件無須或只須做少部分修改,即可繼續(xù)使用,UTF-8 編碼應(yīng)用廣泛,基本所有互聯(lián)網(wǎng)協(xié)議都支持 UTF-8 編碼,是目前編碼方式中優(yōu)先采用的方式之一。

關(guān)于Unicode 與 UTF-8 編碼之間的轉(zhuǎn)換關(guān)系,如下表所示:

在基本多文種平面中約定00D800-00DFFF這范圍用于UTF-16擴(kuò)展標(biāo)識輔助平面(即低位兩個字節(jié)),在UTF-16 中會詳細(xì)介紹。

舉個例子,漢字“聽”的 Unicode 編碼是U+542C,轉(zhuǎn)成UTF-8,步驟如下:

由上表可得出,“聽”字的 Unicode 編碼屬于U+0800到U+D7FF區(qū)域,說明該字占用3個字節(jié),按照1110xxxx-10xxxxxx-10xxxxxx進(jìn)行填充。

U+542C換算成二進(jìn)制:0101-0100-0010-1100。

從低位向高位填充,代替x,11100101-10010000-10101100。

得出漢字“聽”的UTF-8編碼:0xE590AC。

從Unicode 2.0開始,Unicode采用了與ISO 10646-1相同的字庫和字碼;ISO也承諾,ISO 10646將不會替超出U+10FFFF的UCS-4編碼賦值,以使得兩者保持一致。2003年11月 UTF-8 被 RFC 3629重新規(guī)范,只能使用原來Unicode定義的區(qū)域,U+0000到U+10FFFF。如果以上都能理解,那么下表就非常好理解了(摘自Wikipedia):

UTF-8 小結(jié)

在UTF-8文件的開首,以EF,BB,BF代表,以顯示這個文本文件是以UTF-8編碼。

字節(jié)0xFE和0xFF在UTF-8編碼中從未用到,同時(shí),UTF-8以字節(jié)為編碼單元,它的字節(jié)順序在所有系統(tǒng)中都是一様?shù)?,沒有字節(jié)序的問題,也因此它實(shí)際上并不需要BOM(字節(jié)順序標(biāo)記,Byte-Order Mark),但在UTF-16中用來標(biāo)記存儲方式(大端小端)。

ASCII和UTF-8兩種編碼方式下是一樣的,可以說UTF-8是ASCII編碼的父集。

現(xiàn)在我們已經(jīng)知道了UTF-8的含義,以及其編碼原理,下面我們來探究一下 UTF-16 編碼方式。

UTF-16

UTF-16 編碼,以16位無符號整數(shù)為單位進(jìn)行編碼。上文中所提及到的“基本多文種平面”的編碼空間中保留了一塊區(qū)域(從U+D800到U+DFFF),該區(qū)域不映射Unicode字符,UTF-16就是利用保留下來的0xD800-0xDFFF編碼空間來對U+10000到U+10FFFF(即輔助平面)進(jìn)行字符映射的。

在 UTF-16 編碼中,從U+0000至U+D7FF以及從U+E000至U+FFFF的編碼空間的映射關(guān)系同 Unicode,相對應(yīng)于ISO通用字符集中的USC-2。從U+10000到U+10FFFF的編碼空間,UTF-16用一對16比特長的碼元(即32bit,4Bytes)進(jìn)行編碼,熟稱代理對(Surrogate Pair).

0xD800-0xDFFF編碼空間分成兩部分(即上述所說的代理對):

UTF-16的高位代理:從U+D800至U+DBFF,也稱前導(dǎo)代理(lead surrogates)。

UTF-16的低位代理:從U+DC00至U+DFFF,也稱后尾代理(trail surrogates)。

UTF-16 輔助平面編碼方式比較巧妙,從U+10000到U+10FFFF,共計(jì)FFFFF個,即2^(20)個,至少需要20位來表示,我們再來看代理對,先看高半?yún)^(qū),從U+D800到U+DBFF,共計(jì)3FF個,即2^(10)個,同理低半?yún)^(qū)也是2^(10)個,正好為2^(20)個代理對,這也是“基本多語言平面”中保留不對應(yīng)于Unicode字符的2048個碼位的原因。下面我們來看一張表:

舉個例子,古意大利字母"?"的Unicode編碼為U+10300,轉(zhuǎn)成UTF-16,步驟如下:

在0x10300的基礎(chǔ)上先減去0x10000 --> 0x00300,轉(zhuǎn)成二進(jìn)制:0000-0000-0011-0000-0000。

得出高10位(0000-0000-00)和低10位(11-0000-0000)

添加0xD800到高10位(不足補(bǔ)0),得出UTF-16高位:0xD800 + 0x0000 --> 0xD800

添加0xDC00到低10位(不足補(bǔ)0),得出UTF-16低位:0xDC00 + 0x0300 --> 0xDF00

得出古意大利字母"?"的UTF-16BE編碼:U+D800DF00

關(guān)于Unicode 與 UTF-16 編碼之間的轉(zhuǎn)換關(guān)系,如下表所示:

由上表可看出,UTF-16無法兼容ASCII編碼。

UTF-16 存儲形式

想必讀者現(xiàn)在有這樣一個疑惑,UTF-16 是以16位無符號整數(shù)位單位進(jìn)行編碼,即每個字符占用兩個字節(jié),如:在Mac和Window上,對字節(jié)順序的理解是不一樣的,這時(shí)就出現(xiàn)了一個問題,同一字節(jié)流可能會被解釋為不同內(nèi)容,以字符“心“為例,該字符十六進(jìn)制編碼為U+5FC3,按兩個字節(jié)進(jìn)行拆分:5F和C3,在Mac上讀取時(shí)是從低字節(jié)開始,那么在Mac OS會認(rèn)為此U+5FC3編碼為U+C35F,顯示字符為"?",而在Windows上從高字節(jié)開始讀取,則編碼為U+5FC3的字符為“心”。為了解決該問題,字節(jié)順序標(biāo)記(Byte-Order Mark, BOM)誕生,字符U+FEFF如果出現(xiàn)在字節(jié)流的開頭,則用來標(biāo)識該字節(jié)流的字節(jié)序,是高位在前還是低位在前,反之同理。這兩種字節(jié)序在計(jì)算機(jī)我們通常稱大端和小端,下面我們來繼續(xù)探究一下。

大端存儲和小端存儲

大端存儲(Big Endian, 簡稱BE):一個字中的高位字節(jié)放在內(nèi)存中這個字區(qū)域的低地址。小端存儲(Little Endian, 簡稱LE):即一個字中的低位字節(jié)放在內(nèi)存中這個字區(qū)域的低地址處。

還是以古意大利字母"?"為例,我們剛已計(jì)算出其UTF-16編碼為U+D800DF00,如果采用大端存儲,編碼存儲的序列為D800 DF00,采用小端存儲,則為00D8 00DF。這個兩個存儲模式的區(qū)別在于字中字節(jié)的存儲順序不同,而字的存儲順序是相同的。再看幾個例子(摘自Wikipedia):

UTF-16 小結(jié)

在UTF-16文件的開首,以FEFF 或者 FFFE代表,以顯示這個文本文件是以BE存儲編碼還是以LE存儲編碼。

UTF-16編碼可以說是UCS-2的父集,對于小于0x10000的Unicode碼,UTF-16編碼就等于UCS碼,也可以說UTF-16編碼就等于Unicode標(biāo)量值。

UTF-16 VS UTF-8,個人覺得這兩種編碼方式?jīng)]有可比性,主要取決于字符本身主要集中在哪個平面,兩者都是可變長度編碼。

UTF-16 VS UCS-21,如果這個字超過U+FFFF(如:U+10000至U+10FFFF),那么就無法用UCS-2的格式編碼,UTF-16可看成是UCS-2的父集。

相關(guān)文章及鏈接

字符編碼筆記:ASCII,Unicode和UTF-8

Unicode Wikipedia

UTF-8 Wikipedia

字節(jié)順序標(biāo)記 Wikipedia

UTF-16 Wikipedia

Unicode 字符平面映射

UCS即ISO 10646的通用字符集(Universal Character Set, 簡稱UCS),UCS-2我們可以簡單理解為UTF-16,同樣使用16位的編碼空間。 ?

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/66585.html

相關(guān)文章

  • 字符編碼的那些事

    摘要:由于編碼只編碼英文字符,如果要使用漢字則要使用一種新的編碼編碼,而編碼漢字僅僅一個字節(jié)存儲的整數(shù)是不夠的,所以編碼漢字至少需要兩個字節(jié)。 字符串編碼常見的有ASCII碼,Unciode編碼和UTF-8編碼等,那么這些字符串編碼他們的作用是什么?他們之間又有何聯(lián)系?下面讓本人來由淺入深來講解這些編碼。 由ASCII碼說起 我們知道,計(jì)算機(jī)只能存儲二進(jìn)制,不能存儲字符,如果要存儲字符,必須...

    HtmlCssJs 評論0 收藏0
  • 跟著大彬讀源碼 - Redis 5 - 對象和數(shù)據(jù)類型(上)

    摘要:對象源碼結(jié)構(gòu)如下對象類型對象編碼引用統(tǒng)計(jì)指向底層實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)的指針字段對象類型,就是我們常說的。。對象編碼對應(yīng)跳躍表壓縮列表集合動態(tài)字符串等八種底層數(shù)據(jù)結(jié)構(gòu)。 相信很多人應(yīng)該都知道 Redis 有五種數(shù)據(jù)類型:字符串、列表、哈希、集合和有序集合。但這五種數(shù)據(jù)類型是什么含義?Redis 的數(shù)據(jù)又是怎樣存儲的?今天我們一起來認(rèn)識下 Redis 這五種數(shù)據(jù)結(jié)構(gòu)的含義及其底層實(shí)現(xiàn)。 首先要明確...

    antz 評論0 收藏0
  • 字符編碼的那些事

    摘要:字符編碼的那些事前言之前看到中對擴(kuò)展了不少新特性,字符串操作更加友好,比如,,。其中涉及到不少字符編碼的知識,為了更好理解這些新特性,本文對字符編碼相關(guān)知識做一個較全面的梳理和總結(jié)。 字符編碼的那些事 前言 之前看到ES6中對String擴(kuò)展了不少新特性,字符串操作更加友好,比如u{1f914},codePointAt(),String.fromCodePoint()。其中涉及到不少字...

    shadajin 評論0 收藏0
  • 字符編碼的那些事

    摘要:字符編碼的那些事前言之前看到中對擴(kuò)展了不少新特性,字符串操作更加友好,比如,,。其中涉及到不少字符編碼的知識,為了更好理解這些新特性,本文對字符編碼相關(guān)知識做一個較全面的梳理和總結(jié)。 字符編碼的那些事 前言 之前看到ES6中對String擴(kuò)展了不少新特性,字符串操作更加友好,比如u{1f914},codePointAt(),String.fromCodePoint()。其中涉及到不少字...

    kviccn 評論0 收藏0

發(fā)表評論

0條評論

UnixAgain

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<