參考https://www.cnblogs.com/wjhlinux/articles/11096142.html
https://www.liaoxuefeng.com/wiki/1016959663602400/1017075323632896
背景:首先字符串也是一種數(shù)據(jù)類型双饥,但是,字符串比較特殊的是還有一個編碼問題。
而 計算機只能處理數(shù)字,如果要處理文本卿操,就必須先把文本轉(zhuǎn)換為數(shù)字才能處理谆沃。最早的計算機在設(shè)計時采用8個比特(bit)作為一個字節(jié)(byte)快骗,所以纫谅,一個字節(jié)能表示的最大的整數(shù)就是255(二進制11111111=十進制255),如果要表示更大的整數(shù)再登,就必須用更多的字節(jié)尔邓。比如兩個字節(jié)可以表示的最大整數(shù)是65535,4個字節(jié)可以表示的最大整數(shù)是4294967295锉矢。
通過上一節(jié)講的二進制的知識梯嗽,大家已經(jīng)知道計算機只認(rèn)識二進制,生活中的數(shù)字要想讓計算機理解就必須轉(zhuǎn)換成二進制沽损。十進制到二進制的轉(zhuǎn)換只能解決計算機理解數(shù)字的問題灯节,那么文字要怎么讓計算機理解呢?
于是我們就選擇了一種曲線救國的方式,既然數(shù)字可以轉(zhuǎn)換成十進制显晶,我們只要想辦法把文字轉(zhuǎn)換成數(shù)字,這樣文字不就可以表示成二進制了么壹士?
可文字應(yīng)該怎么轉(zhuǎn)換成數(shù)字呢磷雇?那就是強制轉(zhuǎn)換,簡單粗暴躏救。 人們強行約定了一個表唯笙,把文字和數(shù)字對應(yīng)上,這張表就相當(dāng)于翻譯盒使,我們可以拿著一個數(shù)字來對比對應(yīng)表找到相應(yīng)的文字崩掘,反之亦然
ASCII 碼
ASCII 是 American Standard Code for Information Interchange 的縮寫
由于計算機是美國人發(fā)明的,因此少办,最早只有127個字符被編碼到計算機里苞慢,也就是大小寫英文字母、數(shù)字和一些符號英妓,這個編碼表被稱為ASCII編碼挽放,比如大寫字母A的編碼是 65,小寫字母 z的編碼是 122蔓纠。后128個稱為擴展ASCII碼辑畦。
這張表就是計算機顯示各種文字、符號的基石呀
GB2312 & GBK
英文問題是解決了腿倚, 我們中文如何顯示呢纯出? 美國佬設(shè)計ASSCII碼的時候應(yīng)該是沒考慮中國人有一天也能用上電腦,
所以根本沒考慮中文的問題敷燎,上世界80年代(1980)暂筝,電腦進入中國,把磚家們難倒了懈叹, 最后我們設(shè)計出了GB2312編碼表乖杠,長成下面的樣子。一共存了6763個漢字
這里還需要兼容ASCII情況澄成,不然容易存儲變大胧洒,但是不能用2個字節(jié)表示一個英文字母。即遇到中文用2個字節(jié)墨状,遇到英文直接用ASCII的編碼卫漫。怎么做到的呢? 中國人如此聰明肾砂,決定列赎,如果2個字節(jié)連在一起,且每個字節(jié)的第1位(也就是相當(dāng)于128的那個2進制位)如果是1镐确,就代表這是個中文包吝,這個首位是128的字節(jié)被稱為高字節(jié)饼煞。 也就是2個高字節(jié)連在一起,必然就是一個中文诗越。你怎么如此篤定砖瞧?因為0-127已經(jīng)表示了英文的絕大部分字符,128-255是ASCII的擴展表嚷狞,表示的都是極特殊的字符块促,一般沒什么用。所以中國人就直接拿來用了床未。
自1980年發(fā)布gb2312之后竭翠,中文一直用著沒啥問題,隨著個人電腦進入千家萬戶薇搁,有人發(fā)現(xiàn)斋扰,自己的名字竟然打印不出來,因為起的太生僻了只酥。 于是1995年褥实, 磚家們又升級了gb2312, 加入更多字符,連什么藏語裂允、維吾爾語损离、日語、韓語绝编、蒙古語什么的統(tǒng)統(tǒng)都包含進去了僻澎,國家統(tǒng)一亞洲的野心從這些基礎(chǔ)工作中就可見一斑哈。 這個編碼叫GBK十饥,一直到現(xiàn)在窟勃,我們的windows電腦中文版本的編碼就是GBK。
編碼混戰(zhàn)時代
中國人在搞自己編碼的同時逗堵,世界上其它非英語國家也得用電腦呀秉氧,于是都搞出了自己的編碼,你可以想得到的是蜒秤,全世界有上百種語言汁咏,日本把日文編到Shift_JIS里,韓國把韓文編到Euc-kr里作媚,
各國有各國的標(biāo)準(zhǔn)攘滩,就會不可避免地出現(xiàn)沖突,結(jié)果就是纸泡,在多語言混合的文本中漂问,顯示出來會有亂碼。之前你從玩?zhèn)€日本游戲,往自己電腦上一裝蚤假,就顯示亂碼了栏饮。
Unicode
這么亂極大了阻礙了不同國家的信息傳遞,于是聯(lián)合國出面磷仰,發(fā)誓要解決這個混亂局面抡爹。
因此,Unicode應(yīng)運而生芒划。Unicode把所有語言都統(tǒng)一到一套編碼里,這樣就不會再有亂碼問題了欧穴。Unicode 2-4字節(jié) 已經(jīng)收錄136690個字符民逼,并還在一直不斷擴張中…
Unicode標(biāo)準(zhǔn)也在不斷發(fā)展,但最常用的是用兩個字節(jié)表示一個字符(如果要用到非常偏僻的字符涮帘,就需要4個字節(jié))∑床裕現(xiàn)代操作系統(tǒng)和大多數(shù)編程語言都直接支持Unicode。
Unicode有2個特點:
1.支持全球所有語言
2.可以跟各種語言的編碼自由轉(zhuǎn)換调缨,也就是說疮鲫,即使你gbk編碼的文字 ,想轉(zhuǎn)成unicode很容易弦叶。
UTF-8
新的問題又出現(xiàn)了:如果統(tǒng)一成Unicode編碼俊犯,亂碼問題從此消失了。但是伤哺,如果你寫的文本基本上全部是英文的話燕侠,用Unicode編碼比ASCII編碼需要多一倍的存儲空間,由于計算機的內(nèi)存比較大立莉,并且字符串在內(nèi)容中表示時也不會特別大绢彤,所以內(nèi)容可以使用unicode來處理,但是存儲和網(wǎng)絡(luò)傳輸時一般數(shù)據(jù)都會非常多蜓耻,那么增加1倍將是無法容忍的C2啊!刹淌!
為了解決存儲和網(wǎng)絡(luò)傳輸?shù)膯栴}饶氏,出現(xiàn)了Unicode Transformation Format,學(xué)術(shù)名UTF芦鳍,即:對unicode字符進行轉(zhuǎn)換嚷往,以便于在存儲和網(wǎng)絡(luò)傳輸時可以節(jié)省空間!
UTF-8: 使用1、2柠衅、3皮仁、4個字節(jié)表示所有字符;優(yōu)先使用1個字符、無法滿足則使增加一個字節(jié)贷祈,最多4個字節(jié)趋急。英文占1個字節(jié)、歐洲語系占2個势誊、東亞占3個呜达,其它及特殊字符占4個
UTF-16: 使用2、4個字節(jié)表示所有字符粟耻;優(yōu)先使用2個字節(jié)查近,否則使用4個字節(jié)表示。
UTF-32: 使用4個字節(jié)表示所有字符挤忙;
總結(jié):UTF 是為unicode編碼 設(shè)計 的一種 在存儲 和傳輸時節(jié)省空間的編碼方案霜威。
如果你要傳輸?shù)奈谋景罅坑⑽淖址肬TF-8編碼就能節(jié)省空間:
字符 | ASCII | Unicode | UTF-8 |
---|---|---|---|
A | 01000001 | 00000000 | 0100000101000001 |
中 | x | 01001110 00101101 | 11100100 10111000 10101101 |
utf-8解碼是一個字節(jié)的解碼册烈,如果第一個字節(jié)的第一位為0戈泼,則為單字節(jié)字符,如果第一字節(jié)赏僧,從第一位開始大猛,連續(xù)有幾個1,就表示該字符占用幾個字節(jié)淀零。
‘中’的utf-8編碼挽绩,第一個字節(jié)有3個連續(xù)的1,則占用3個字符,如此系統(tǒng)即可正確解析(這里解碼還是學(xué)的GB2312)
從上面的表格還可以發(fā)現(xiàn)驾中,UTF-8編碼有一個額外的好處琼牧,就是ASCII編碼實際上可以被看成是UTF-8編碼的一部分,所以哀卫,大量只支持ASCII編碼的歷史遺留軟件可以在UTF-8編碼下繼續(xù)工作巨坊。
搞清楚了ASCII、Unicode和UTF-8的關(guān)系此改,我們就可以總結(jié)一下現(xiàn)在計算機系統(tǒng)通用的字符編碼工作方式:
在計算機內(nèi)存中趾撵,統(tǒng)一使用Unicode編碼,當(dāng)需要保存到硬盤或者需要傳輸數(shù)據(jù)的時候共啃,就轉(zhuǎn)換為UTF-8編碼占调。
UTF-8 是一種不定長的Unicode 編碼方式,一個字符可能占用1個字節(jié)移剪,也有可能占用2,3,4 個字節(jié)究珊。
內(nèi)存存儲字節(jié)流的時候,字符不定長會給算法帶來麻煩纵苛。比如你沒法確定第2000個字符在哪個字節(jié)開始剿涮。
用記事本編輯的時候言津,從文件讀取的UTF-8字符被轉(zhuǎn)換為Unicode字符到內(nèi)存里,編輯完成后取试,保存的時候再把Unicode轉(zhuǎn)換為UTF-8保存到文件悬槽。
常用編碼介紹一覽表
編碼 | 制定時間 | 作用 | 所占字節(jié)數(shù) |
---|---|---|---|
ASCII | 1967年 | 表示英語及西歐語言 | 8bit1bytes |
GB2312 | 1980年 | 國家簡體中文字符集,兼容ASCII | 2bytes |
Unicode | 1991年 | 國際標(biāo)準(zhǔn)組織統(tǒng)一標(biāo)準(zhǔn)字符集 | 2bytes |
GBK | 1995年 | 兼容GB2312瞬浓,支持繁體初婆,日韓文等 | 2bytes |
UTF-8 | 1992年 | 不定長編碼 | 1-3bytes |