計(jì)算機(jī)中的字符編碼

計(jì)算機(jī)只能處理二進(jìn)制的數(shù)據(jù)什燕,其它形式的數(shù)據(jù)都只能轉(zhuǎn)換為二進(jìn)制后才能被cpu處理及存儲(chǔ)载迄。轉(zhuǎn)換就涉及到要有一套字符編碼岛啸,即字符與二進(jìn)制的對(duì)應(yīng)關(guān)系徘钥。

1. ASCII 編碼

全稱American Standard Code for Information Interchange 美國信息交換標(biāo)準(zhǔn)代碼,上個(gè)世紀(jì)60年代离赫,美國制定的一套字符編碼芭逝,對(duì)英語字符與二進(jìn)制位之間的關(guān)系,做了統(tǒng)一規(guī)定渊胸。ASCII用1個(gè)字節(jié)(8位二進(jìn)制)來表示一個(gè)字符旬盯,因此八個(gè)二進(jìn)制位就可以組合出256種狀態(tài)(從0000000到11111111),但ASCII碼一共規(guī)定了128個(gè)字符的編碼翎猛,只占用了一個(gè)字節(jié)的后面7位胖翰,最前面的1位統(tǒng)一規(guī)定為0。比如:字母a切厘,用二進(jìn)制表示01100001(十進(jìn)制值為97)萨咳。

部分ASCII碼對(duì)應(yīng)值

英語128個(gè)符號(hào)編碼已足夠,但是顯示不同國家的語言時(shí)疫稿,128個(gè)符號(hào)是不夠的培他。于是有的國家開始利用ASCII編碼里的高位,0—127表示的符號(hào)是一樣的遗座,不同國家在128—255這一段所表示的字符卻不同舀凛。在字符比較多的國家,255個(gè)字符也是不夠的途蒋,因此仍采用1個(gè)字節(jié)的編碼受到限制猛遍。
其它國家為了顯示本國的語言,都對(duì)ASCII碼進(jìn)行了擴(kuò)展号坡,加入了本國的語言編碼螃壤,這種編碼方式為ANSI編碼,用2個(gè)字節(jié)來表示筋帖,ANSI編碼跟操作系統(tǒng)有直接關(guān)系,你安裝什么操作系統(tǒng)冤馏,那你的ANSI編碼就是相應(yīng)的編碼日麸。例如:我們安裝的是中文操作系統(tǒng),對(duì)應(yīng)的默認(rèn)編碼GB2312逮光。

  • GB2312編碼:簡體中文代箭、全角字符編碼,理論上最多表示65536個(gè)漢字涕刚;
  • GBK編碼:對(duì)GB2312進(jìn)行了擴(kuò)展嗡综,用于顯示罕見漢字;
  • BIG5編碼:繁體漢字編碼杜漠;
  • JIS編碼:日本文字編碼极景。

2. Unicode

在打開一個(gè)文本文件之前察净,需要知道它的編碼方式,否則用錯(cuò)誤的編碼方式解讀盼樟,就會(huì)出現(xiàn)亂碼氢卡。這是因?yàn)椋澜缟洗嬖谥喾N編碼方式晨缴,同一個(gè)二進(jìn)制數(shù)字可以被解釋成不同的符號(hào)译秦。

若有一種編碼,將世界上所有的符號(hào)都納入其中击碗,每一個(gè)符號(hào)都給予一個(gè)獨(dú)一無二的編碼筑悴,就可以解決亂碼問題,Unicode應(yīng)運(yùn)而生稍途。

Unicode編碼集合可以容納100多萬個(gè)符號(hào)耘沼,每個(gè)符號(hào)的編碼都不一樣良蒸。比如U+0042表示英語的大寫字母"B",U+1F600表示"??",U+8DF3表示漢字"跳"娘摔。具體的符號(hào)對(duì)應(yīng)表,可以查詢unicode.org太雨、Unicode Utilities或者專門的漢字對(duì)應(yīng)表蕊退。

Unicode編碼的符號(hào)集只規(guī)定了符號(hào)的二進(jìn)制代碼,卻沒有規(guī)定這個(gè)二進(jìn)制代碼應(yīng)該如何存儲(chǔ)猖吴。比如漢字"跳"的unicode是十六進(jìn)制數(shù)8DF3摔刁,轉(zhuǎn)換成二進(jìn)制數(shù)足足有15位(1000110111110011),也就是說這個(gè)符號(hào)的表示至少需要2個(gè)字節(jié)海蔽。也會(huì)有序號(hào)更大的符號(hào)共屈,可能需要3、4個(gè)字節(jié)党窜,甚至更多拗引。
那么,如何才能區(qū)別Unicode和ASCII幌衣?Unicode編碼怎么在計(jì)算機(jī)內(nèi)存儲(chǔ)呢矾削?若每個(gè)符號(hào)都占用四個(gè)字節(jié)編碼表示,那么每個(gè)英文字母前三個(gè)字節(jié)是0豁护,極大的浪費(fèi)存儲(chǔ)空間哼凯,原英文文本文件的大小會(huì)因此大出三倍,顯然無法接受楚里。

3. UTF-8

UTF-8是Unicode的實(shí)現(xiàn)方式之一断部,這種Unicode/UTF-8統(tǒng)一編碼方式有利于數(shù)據(jù)的傳輸和計(jì)算機(jī)科學(xué)的發(fā)展。其他實(shí)現(xiàn)方式還包括UTF-16(字符用兩個(gè)字節(jié)或四個(gè)字節(jié)編碼)和UTF-32(字符用四個(gè)字節(jié)編碼)班缎,不過在互聯(lián)網(wǎng)上基本不用蝴光。

UTF-8的編碼規(guī)則:

  1. 對(duì)于單字節(jié)的字符她渴,字節(jié)的第一位設(shè)為0,后面7位為這個(gè)符號(hào)的Unicode虱疏,因此對(duì)于英語字符惹骂,UTF-8和ASCII碼相同;
  2. 對(duì)于n字節(jié)的字符(n>1)做瞪,第一個(gè)字節(jié)的前n位都設(shè)為1对粪,第n+1位設(shè)為0,后面字節(jié)的前兩位一律設(shè)為10装蓬。剩下的沒有提及的二進(jìn)制位著拭,全部為這個(gè)符號(hào)的unicode碼。

Unicode符號(hào)范圍 | UTF-8編碼方式
(十六進(jìn)制)|(二進(jìn)制)
--------------------+---------------------------------------------
0000 0000 — 0000 007F | 0xxxxxxx
0000 0080 — 0000 07FF | 110xxxxx 10xxxxxx
0000 0800 — 0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000 — 0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

已知"跳"的Unicode是4DF3(1000110111110011)牍帚,根據(jù)其值位于的范圍可知儡遮,"跳"的UTF-8編碼是"11101000 10110111 10110011",轉(zhuǎn)換成十六進(jìn)制就是E8B7B3暗赶。

也就是說鄙币,UTF-8編碼是一種變長的編碼,它可以使用1~4個(gè)字節(jié)表示一個(gè)符號(hào)蹂随,根據(jù)不同的符號(hào)而變化字節(jié)長度十嘿。

在Mac上創(chuàng)建一個(gè)txt文檔,在偏好設(shè)置中岳锁,能夠選擇當(dāng)前文檔的存儲(chǔ)編碼方式绩衷,也可進(jìn)行編碼之間的轉(zhuǎn)換:

4. 編碼中的Little endian和Big endian

若將一個(gè)十六進(jìn)制數(shù)據(jù)"8DF3"直接進(jìn)行存儲(chǔ),需要用兩個(gè)字節(jié)存儲(chǔ)激率,一個(gè)字節(jié)是8D咳燕,另一個(gè)字節(jié)是F3。那么乒躺,計(jì)算機(jī)在存儲(chǔ)空間的地址順序上招盲,是將8D在前,還是將F3在前呢嘉冒?

Unicode規(guī)范中定義宪肖,每一個(gè)文件的最前面分別加入一個(gè)表示編碼順序的字符,這個(gè)字符的名字叫做"零寬度非換行空格"(ZERO WIDTH NO-BREAK SPACE)健爬,用FEFF表示。這正好是兩個(gè)字節(jié)么介,而且FF比FE大1娜遵。

如果一個(gè)文本文件的頭兩個(gè)字節(jié)是FE FF,就表示該文件采用大端序壤短;如果頭兩個(gè)字節(jié)是FF FE设拟,就表示該文件采用小端序慨仿。

新建一個(gè)記事本文本文件,輸入一個(gè)漢字作為內(nèi)容纳胧,依次采用ANSI镰吆、Unicode、Unicode big endian 和 UTF-8編碼方式保存跑慕。然后万皿,可以通過"十六進(jìn)制"的形式觀察該文件的內(nèi)部編碼方式、存儲(chǔ)有何不同核行。

1)ANSI:文件的編碼就是兩個(gè)字節(jié)"D1 CF"牢硅,這正是"嚴(yán)"的GB2312編碼,這也暗示GB2312是采用大頭方式存儲(chǔ)的芝雪。

2)Unicode:編碼是四個(gè)字節(jié)"FF FE 25 4E"减余,其中"FF FE"表明是小頭方式存儲(chǔ),真正的編碼是4E25惩系。

3)Unicode big endian:編碼是四個(gè)字節(jié)"FE FF 4E 25"位岔,其中"FE FF"表明是大頭方式存儲(chǔ)。

4)UTF-8:編碼是六個(gè)字節(jié)"EF BB BF E4 B8 A5"抒抬,前三個(gè)字節(jié)"EF BB BF"表示這是UTF-8編碼,后三個(gè)"E4B8A5"就是"嚴(yán)"的具體編碼悴侵,它的存儲(chǔ)順序與編碼順序是一致的。

5. 總結(jié)

在計(jì)算機(jī)內(nèi)存中統(tǒng)一使用Unicode編碼可免,當(dāng)需要保存到硬盤或者需要傳輸?shù)臅r(shí)候,就轉(zhuǎn)換為UTF-8(或其他)編碼浇借。

不同的字符集中,字符有不同的字符編碼妇垢,所以要想判斷某個(gè)輸入的數(shù)據(jù)是不是某類字符的時(shí)候巾遭,先確定當(dāng)前使用的字符集闯估,找到該字符集下該類型字符對(duì)應(yīng)的字符編碼范圍灼舍,即可判斷,如判斷GB2312下的漢字涨薪。

系統(tǒng)只是把這個(gè)字符告訴終端骑素,終端去字體中找到這個(gè)字符對(duì)應(yīng)的圖像,再把這個(gè)圖像顯示出來刚夺。如果字體中沒有献丑,那就會(huì)顯示方框等所謂的亂碼末捣。

emoji的支持也是一樣的,所以實(shí)際上是字體的功勞创橄÷嶙觯可能系統(tǒng)在emoji的渲染上支持一些額外的特性(比如顏色,或者干脆用圖片來代表emoji字符)妥畏。

現(xiàn)代操作系統(tǒng)內(nèi)部都是用Unicode來處理字符的邦邦。設(shè)定字符集實(shí)際上是告訴系統(tǒng)如何處理外碼和內(nèi)碼的對(duì)應(yīng),比如同一個(gè)字符咖熟,在UTF-8和UTF-16中的編碼可能是不同的圃酵,字節(jié)數(shù)量也可能是不同的,但是對(duì)應(yīng)的unicode其實(shí)同一個(gè)馍管。比如系統(tǒng)處理一個(gè)字符郭赐,根據(jù)設(shè)定的字符集找到對(duì)應(yīng)的UTF-8編碼輸出給終端,但是終端卻是用UTF-16的規(guī)則來理解這些編碼确沸,那自然就會(huì)出錯(cuò)了捌锭。

參考文章,感謝:
https://www.cnblogs.com/ooon/p/4818574.html
https://www.cnblogs.com/cthon/p/9297232.html
https://blog.csdn.net/LightUpHeaven/article/details/92001322

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末罗捎,一起剝皮案震驚了整個(gè)濱河市观谦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌桨菜,老刑警劉巖豁状,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異倒得,居然都是意外死亡泻红,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門霞掺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谊路,“玉大人,你說我怎么就攤上這事菩彬〔埃” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵骗灶,是天一觀的道長惨恭。 經(jīng)常有香客問我,道長耙旦,這世上最難降的妖魔是什么脱羡? 我笑而不...
    開封第一講書人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上轻黑,老公的妹妹穿的比我還像新娘琴昆。我一直安慰自己,他們只是感情好抖拦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開白布舷暮。 她就那樣靜靜地躺著,像睡著了一般复颈。 火紅的嫁衣襯著肌膚如雪沥割。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,775評(píng)論 1 307
  • 那天帜讲,我揣著相機(jī)與錄音椒拗,去河邊找鬼。 笑死蚀苛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的译红。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼侦厚,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼刨沦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起想诅,我...
    開封第一講書人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤来破,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后徘禁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡娘荡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年炮沐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了回怜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鲜戒,死狀恐怖抹凳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赢底,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布粹庞,位于F島的核電站洽损,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏碑定。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一漫试、第九天 我趴在偏房一處隱蔽的房頂上張望碘赖。 院中可真熱鬧外构,春花似錦播掷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽般码。三九已至,卻和暖如春板祝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背孤里。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來泰國打工橘洞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人炸枣。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓适肠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親侯养。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356