Unicode字符集的發(fā)展歷史及與UTF-8双戳,ISO8891-1等字符集的關(guān)系

摘要:本文從Unicode入手,介紹由于通信問題而產(chǎn)生的字符集糜芳,以及Unicode的發(fā)展情況飒货。介紹各種字符集的及其使用。并適時(shí)的介紹一些歷史情況峭竣,主要討論字符集在java及C語言環(huán)境中的使用塘辅,及闡述UTF,ISO 8859-1皆撩,ASCII他們之間的關(guān)系扣墩。會(huì)介紹一些亂碼知識(shí),總而言之扛吞,亂碼產(chǎn)生的根本原因就是:編碼與解碼不一致造成的呻惕。

一、概念:

1滥比、BCD碼

最初的計(jì)算機(jī)性能和存儲(chǔ)容量都比較差亚脆,所以普遍采用4位BCD(BinaryCoded Decimal)編碼(這個(gè)編碼出現(xiàn)比計(jì)算機(jī)還早,最早是用在打孔卡上的)盲泛。BCD編碼簡(jiǎn)單點(diǎn)說就是將十進(jìn)制數(shù)用二進(jìn)制表示濒持,如下圖所示。

十進(jìn)制數(shù) 8421BCD編碼
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001

BCD編碼表示數(shù)字還可以寺滚,但表示字母或符號(hào)就很不好用柑营,需要用多個(gè)編碼來表示。后來經(jīng)過演變發(fā)展成了ASCII碼村视。ASCII含33(ASCII碼范圍為:0~31和127)個(gè)控制字符官套, 和95(ASCII碼范圍32~126)個(gè)可顯示字符。

2蚁孔、由ASCII碼發(fā)展到Unicode

ASCII編碼存儲(chǔ)方式:

其中最高位0奶赔,其余七位為0或1,可表示的范圍為:0 ~ 2^7= 0 ~ 128

C語言實(shí)現(xiàn)打印字符A

# include <stdio.h>  
int main()  
{  
    char ch = '65';  
    printf("%c", ch);  
    return 0;  
}  

下圖為ASCII碼表

后來勒虾,就像建造巴比倫塔一樣纺阔,世界各地的都開始使用計(jì)算機(jī)瘸彤,但是很多國家用的不是英文修然,他們的字母里有許多是ASCII里沒有的,為了可以在計(jì)算機(jī)保存他們的文字,他們決定采用127號(hào)之后的空位來表示這些新的字母愕宋、符號(hào)玻靡,還加入了很多畫表格時(shí)需要用下到的橫線、豎線中贝、交叉等形狀囤捻,一直把序號(hào)編到了最后一個(gè)狀態(tài)255。從128到255這一頁的字符集被稱"擴(kuò)展字符集"邻寿。從此之后蝎土,貪婪的人類再?zèng)]有新的狀態(tài)可以用了。

等中國人們得到計(jì)算機(jī)時(shí)绣否,已經(jīng)沒有可以利用的字節(jié)狀態(tài)來表示漢字誊涯,況且有6000多個(gè)常用漢字需要保存呢。但是這難不倒智慧的中國人民蒜撮,我們不客氣地把那些127號(hào)之后的奇異符號(hào)們直接取消掉, 規(guī)定:一個(gè)小于127的字符的意義與原來相同暴构,但兩個(gè)大于127的字符連在一起時(shí),就表示一個(gè)漢字段磨,前面的一個(gè)字節(jié)(他稱之為高字節(jié))從0xA1用到0xF7取逾,后面一個(gè)字節(jié)(低字節(jié))從0xA1到0xFE,這樣我們就可以組合出大約7000多個(gè)簡(jiǎn)體漢字了苹支。在這些編碼里砾隅,我們還把數(shù)學(xué)符號(hào)、羅馬希臘的字母债蜜、日文的假名們都編進(jìn)去了琉用,連在 ASCII 里本來就有的數(shù)字、標(biāo)點(diǎn)策幼、字母都統(tǒng)統(tǒng)重新編了兩個(gè)字節(jié)長(zhǎng)的編碼邑时,這就是常說的"全角"字符,而原來在127號(hào)以下的那些就叫"半角"字符了特姐。

中國人民看到這樣很不錯(cuò)晶丘,于是就把這種漢字方案叫做"GB2312"。GB2312是對(duì)ASCII的中文擴(kuò)展唐含。
但是中國的漢字太多了浅浮,我們很快就就發(fā)現(xiàn)有許多人的人名沒有辦法在這里打出來,特別是某些很會(huì)麻煩別人的國家領(lǐng)導(dǎo)人捷枯。于是我們不得不繼續(xù)把 GB2312 沒有用到的代碼點(diǎn)找出來老實(shí)不客氣地用上滚秩。

后來還是不夠用,于是干脆不再要求低字節(jié)一定是127號(hào)之后的內(nèi)碼淮捆,只要第一個(gè)字節(jié)是大于127就固定表示這是一個(gè)漢字的開始郁油,不管后面跟的是不是擴(kuò)展字符集里的內(nèi)容本股。結(jié)果擴(kuò)展之后的編碼方案被稱為 GBK標(biāo)準(zhǔn),GBK 包括了GB2312 的所有內(nèi)容桐腌,同時(shí)又增加了近20000個(gè)新的漢字(包括繁體字)和符號(hào)拄显。后來少數(shù)民族也要用電腦了,于是我們?cè)贁U(kuò)展案站,又加了幾千個(gè)新的少數(shù)民族的字躬审,GBK 擴(kuò)成了 GB18030。從此之后蟆盐,中華民族的文化就可以在計(jì)算機(jī)時(shí)代中傳承了承边。

由于世界各地都產(chǎn)生了自己的編碼方案,這是給人的溝通帶來了巨大麻煩石挂。于是有一個(gè)叫做ISO的國際組織開始著手解決這個(gè)問題炒刁,想用一種規(guī)范來表示出所有的語言。于是Unicode就這樣產(chǎn)生了誊稚。注意:Unicode是內(nèi)存編碼表示方案(是規(guī)范)翔始,而UTF是如何保存和傳輸U(kuò)nicode的方案(是實(shí)現(xiàn))這也是UTF與Unicode的區(qū)別。

字符是各種文字和符號(hào)的總稱里伯,包括各個(gè)國家文字城瞎、標(biāo)點(diǎn)符號(hào)、圖形符號(hào)疾瓮、數(shù)字等脖镀。字符集是多個(gè)字符的集合,字符集種類較多狼电,每個(gè)字符集包含的字符個(gè)數(shù)不同蜒灰,常見字符集有:ASCII字符集、ISO 8859字符集肩碟、GB2312字符集强窖、BIG5字符集、GB18030字符集削祈、Unicode字符集等翅溺。
各個(gè)國家和地區(qū)在制定編碼標(biāo)準(zhǔn)的時(shí)候,“字符的集合”和“編碼”一般都是同時(shí)制定的髓抑。因此咙崎,平常我們所說的“字符集”,比如:GB2312, GBK, JIS 等吨拍,除了有“字符的集合”這層含義外褪猛,同時(shí)也包含了“編碼”的含義。

3羹饰、ISO 8859-1

ISO/IEC8859-1伊滋,又稱Latin-1或“西歐語言”碳却,是國際標(biāo)準(zhǔn)化組織內(nèi)ISO/IEC 8859的第一個(gè)8位字符集。它以ASCII為基礎(chǔ)新啼,在空置的0xA0-0xFF的范圍內(nèi),加入96個(gè)字母及符號(hào)刹碾,藉以供使用變音符號(hào)的拉丁字母語言使用燥撞。iOS 8859-1表示的字符就是Unicode的0x0000-0x00ff之間的字符。

Paste_Image.png

在下文代碼頁中有關(guān)于ISO 8859-1與Windows-1252的區(qū)別迷帜。

4物舒、Unicode編碼詳解

Unicode字符集可以簡(jiǎn)寫為UCS(Unicode Character Set),0x0000~0X00ff與ISO 8859-1保持一致
Unicode可以邏輯分為17平面(Plane)戏锹,每個(gè)平面擁有65536( = 2^16)個(gè)代碼點(diǎn)冠胯,雖然目前只有少數(shù)平面被使用。

平面0 (0000–FFFF): 基本多文種平面(Basic Multilingual Plane, BMP).

平面1 (10000–1FFFF): 多文種補(bǔ)充平面(SupplementaryMultilingual Plane, SMP).

平面2 (20000–2FFFF): 表意文字補(bǔ)充平面(SupplementaryIdeographic Plane, SIP).

平面3 (30000–3FFFF): 表意文字第三平面(TertiaryIdeographic Plane, TIP).

平面4 to 13 (40000–DFFFF)尚未使用

平面14 (E0000–EFFFF): 特別用途補(bǔ)充平面(SupplementarySpecial-purpose Plane, SSP)

平面15 (F0000–FFFFF)保留作為私人使用區(qū)(PrivateUse Area, PUA)平面16 (100000–10FFFF)锦针,保留作為私人使用區(qū)(PrivateUse Area, PUA)

中荠察、日、韓的三種文字占用了Unicode中0x3000(12288)到0x9FFF(40959)的部分奈搜,共計(jì)28671個(gè)字符悉盆;
而中文在BMP中的范圍是:U+4E00到U+9FA5之間是漢字的Unicode編碼。

5馋吗、 UTF格式詳解

UTFUnicode Transformation Format的縮寫焕盟。是Unicode的一種實(shí)現(xiàn)方案。任何文字在Unicode中都對(duì)應(yīng)一個(gè)值宏粤,這個(gè)值稱為代碼點(diǎn)也叫碼位(CodePoint)脚翘。代碼點(diǎn)的值通常寫為:U+ABCD,在Java中可以直接將一個(gè)字符賦值為

public class Test1 {  
    public static void main(String[] args) throws Exception {  
        char ch = '\u6211';  
        System.out.println(ch);  
    }  
}  

輸出結(jié)果:我
UTF-8四種具體實(shí)現(xiàn)方式:
1.第一種是一個(gè)字節(jié)的編碼:即128個(gè)ascii字符(只需要一個(gè)字節(jié))

格式:0xxxxxxx
2^7 - 1 = 127 = 7F = (0111-1111)
 編碼方式Unicoe范圍由(U+0000 至 U+007F)

**2.第二種是兩個(gè)字節(jié)的編碼:即帶有符號(hào)的拉丁文绍哎,希臘文来农,西里爾字母,亞美尼亞語崇堰,希伯來文备图,阿拉伯文等,則需要兩個(gè)字節(jié)編碼(Unicode 范圍由U+0080至U+07FF) **

格式:110xxxxx 10xxxxxx
(0080)16  =  (128)10
(07FF) 16 = (2047)10 = 2^11-1;

3.第三種是三字節(jié)的編碼赶袄,即其他多文種平面(BMP)中的字符(這包括了大部分的漢字)(范圍為: U+0800 至 U+FFFF)

格式:1110xxxx 10xxxxxx 10xxxxxx
U+0800 = 2048揽涮;
U+FFFF = 65535 = 2^16 -1;
1110xxxx  10xxxxxx 10xxxxxx

4.第四種是4-6字節(jié)編碼饿肺。

U+1 0000至U+1 FFFFF:使用四字節(jié)
U+20 0000 至U+3FF FFFF:使用五字節(jié)
U+400 0000至U+7FFF FFFF

例如“漢”字的Unicode編碼是6C49蒋困。6C49在0800-FFFF之間,所以肯定要用3字節(jié)模板了:1110xxxx 10xxxxxx 10xxxxxx敬辣。將6C49寫成二進(jìn)制是:0110 110001 001001雪标, 用這個(gè)比特流依次代替模板中的x零院,得到:11100110 10110001 10001001,即E6 B1 89村刨。
目前計(jì)算機(jī)一般使用 2 個(gè)字節(jié)(16 位)來存放一個(gè)序號(hào)(DBCS,DoubleByte Character System)告抄,因此,這種方式存放的字符也被稱作寬字節(jié)字符嵌牺。比如打洼,字符串"中文123" 在 Windows2000 下,內(nèi)存中實(shí)際存放的是 5 個(gè)字符逆粹,一共10個(gè)字節(jié)募疮;若在gb2312編碼中,共計(jì)五個(gè)字符僻弹,7個(gè)字節(jié)阿浓。

UTF-16和UCS-2區(qū)別與聯(lián)系

UTF-16和UCS-2都是Unicode的編碼方式。

Unicode使用一個(gè)確定的名字和一個(gè)叫做碼位(code point)的整數(shù)來定義一個(gè)字符蹋绽。例如?字符被命名為“copyright sign”并且有一個(gè)值為U+00A9(0xA9芭毙,十進(jìn)制169)的碼位。
Unicode的碼空間從U+0000到U+10FFFF卸耘,共有1,112,064個(gè)碼位(code point)可用來映射字符. Unicode的碼空間可以劃分為17個(gè)平面(plane)稿蹲,每個(gè)平面包含216
(65,536)個(gè)碼位。每個(gè)平面的碼位可表示為從U+xx0000到U+xxFFFF, 其中xx表示十六進(jìn)制值從0016
到1016
鹊奖,共計(jì)17個(gè)平面苛聘。

第一個(gè)Unicode平面(碼位從U+0000至U+FFFF)包含了最常用的字符,該平面被稱為基本多語言平面(Basic Multilingual Plane)忠聚,縮寫為BMP设哗。其他平面稱為輔助平面(Supplementary Planes)。
UCS-2 (2-byte Universal Character Set)是一種定長(zhǎng)的編碼方式两蟀,UCS-2僅僅簡(jiǎn)單的使用一個(gè)16位碼元來表示碼位网梢,也就是說在0到0xFFFF的碼位范圍內(nèi),它和UTF-16基本一致赂毯。
UTF-16 (16-bit Unicode Transformation Format)是UCS-2的拓展战虏,它可以表示BMP以為的字符。UTF-16使用一個(gè)或者兩個(gè)16位的碼元來表示碼位党涕,這樣就可以對(duì)0到0x10FFFF的碼位進(jìn)行編碼烦感。
例如,在UCS-2和UTF-16中膛堤,BMP中的字符U+00A9 copyright sign(?)都被編碼為0x00A9手趣。
但是在BMP之外的字符,例如??肥荔,只能用UTF-16進(jìn)行編碼绿渣,使用兩個(gè)16為碼元來表示:0xD834 0xDF06朝群。這被稱作代理對(duì),值得注意的是一個(gè)代理對(duì)僅僅表示一個(gè)字符中符,而不是兩個(gè)姜胖。UCS-2并沒有代理對(duì)的概念,所以會(huì)將0xD834 0xDF06解釋為兩個(gè)字符淀散。
簡(jiǎn)單的說右莱,UTF-16可看成是UCS-2的父集。在沒有輔助平面字符(surrogate code points)前吧凉,UTF-16與UCS-2所指的是同一的意思隧出。(嚴(yán)格的說這并不正確踏志,因?yàn)樵赨TF-16中從U+D800到U+DFFF的碼位不對(duì)應(yīng)于任何字符阀捅,而在使用UCS-2的時(shí)代,U+D800到U+DFFF內(nèi)的值被占用针余。)但當(dāng)引入輔助平面字符后饲鄙,就稱為UTF-16了。

6圆雁、代碼頁及字符集對(duì)照表

Windows將字符集稱作代碼頁忍级。代碼頁是字符集編碼的別名,也有人稱"內(nèi)碼表",

代碼頁 名稱 顯示名稱
37 IBM037 IBM EBCDIC(美國 - 加拿大)
936 gb2312 簡(jiǎn)體中文 (GB2312)
950 big5 繁體中文 (Big5)
1200 utf-16 Unicode(Little-Endian)
1201 UnicodeFFFE Unicode (Big-Endian)
28591 Windows-28591 ISO-8859-1
65001 UTF-8 UTF-8
7伪朽、ISO-8859-1和Windows-1252的區(qū)別

ISO-8859-1轴咱,正式編號(hào)為ISO/IEC 8859-1:1998,又稱Latin-1或“西歐語言”烈涮,是國際標(biāo)準(zhǔn)化組織內(nèi)ISO/IEC 8859的第一個(gè)8位字符集朴肺。它以ASCII為基礎(chǔ),在空置的0xA0-0xFF的范圍內(nèi)坚洽,加入96個(gè)字母及符號(hào)戈稿,藉以供使用附加符號(hào)的拉丁字母語言使用。Unicode的前0-255個(gè)字符與ISO-8859-1相一致讶舰。

Windows-1252經(jīng)常被錯(cuò)誤地貼上ISO-8859-1的標(biāo)簽鞍盗,因?yàn)樗鼈兪窒嗨啤3?28到159(十六進(jìn)制80到9F)范圍內(nèi)的很少使用的C1控制字符被替換為額外的字符外跳昼,Windows-1252代碼頁的字符和ISO-8859-1完全一致般甲。Windows-28591代碼頁才是真正的ISO-8859-1,然而鹅颊,英文版的Windows 7系統(tǒng)上似乎沒有Windows-28591代碼頁欣除,至于其他系統(tǒng)有沒有我就不知道了。Windows-1252是ISO的超集挪略。

UTF-16與UCS-2的聯(lián)系與區(qū)別:
UTF-16和UCS-2都是Unicode的編碼方式历帚。Unicode使用一個(gè)確定的名字和一個(gè)叫做代碼點(diǎn)(code point)的整數(shù)來定義一個(gè)字符滔岳。例如?字符被命名為“copyright sign”并且有一個(gè)值為U+00A9(0xA9,十進(jìn)制169)的代碼點(diǎn)挽牢。

Unicode的碼空間為U+0000到U+10FFFF谱煤,共有1,112,064個(gè)代碼點(diǎn)(code point)可用來映射字符. Unicode的碼空間可以劃分為17個(gè)平面(plane),每個(gè)平面包含216(65,536)個(gè)代碼點(diǎn)禽拔。每個(gè)平面的代碼點(diǎn)可表示為從U+xx0000到U+xxFFFF, 其中xx表示十六進(jìn)制值從0016 到1016刘离,共計(jì)17個(gè)平面。

第一個(gè)Unicode平面(代碼點(diǎn)從U+0000至U+FFFF)包含了最常用的字符睹栖,該平面被稱為基本多語言平面(Basic Multilingual Plane)硫惕,縮寫為BMP。其他平面稱為輔助平面(Supplementary Planes)野来。

UCS-2 (2-byte UniversalCharacter Set)是一種定長(zhǎng)的編碼方式恼除,UCS-2僅僅簡(jiǎn)的使用一個(gè)16位碼元來表示代碼點(diǎn),也就是說在0到0xFFFF的代碼點(diǎn)范圍內(nèi)曼氛,它和UTF-16基本一致豁辉。

UTF-16 (16-bit UnicodeTransformation Format)是UCS-2的拓展,它可以表示BMP以為的字符舀患。UTF-16使用一個(gè)或者兩個(gè)16位的碼元來表示代碼點(diǎn)徽级,這樣就可以對(duì)0到0x10FFFF的代碼點(diǎn)進(jìn)行編碼。
例如聊浅,在UCS-2和UTF-16中餐抢,BMP中的字符U+00A9copyright sign(?)都被編碼為0x00A9。
但是在BMP之外的字符低匙,例如旷痕,只能用UTF-16進(jìn)行編碼,使用兩個(gè)16位碼元來表示:0xD834 0xDF06努咐。這被稱作代理對(duì)苦蒿,值得注意的是一個(gè)代理對(duì)僅僅表示一個(gè)字符,而不是兩個(gè)渗稍。UCS-2并沒有代理對(duì)的概念佩迟,所以會(huì)將0xD834 0xDF06解釋為兩個(gè)字符。

簡(jiǎn)單的說竿屹,UTF-16可看成是UCS-2的父集报强。在沒有輔助平面字符(surrogate code points)前,UTF-16與UCS-2所指的是同一的意思拱燃。(嚴(yán)格的說這并不正確秉溉,因?yàn)樵赨TF-16中從U+D800到U+DFFF的代碼點(diǎn)不對(duì)應(yīng)于任何字符,而在使用UCS-2的時(shí)代,U+D800到U+DFFF內(nèi)的值被占用召嘶。)但當(dāng)引入輔助平面字符后父晶,就稱為UTF-16了。
但UCS-2只是一個(gè)編碼方案弄跌,UTF-16卻要用于實(shí)際的傳輸甲喝,所以就不得不考慮字節(jié)序的問題。

8铛只、UTF的字節(jié)序和BOM

UTF-8以字節(jié)為編碼單元埠胖,沒有字節(jié)序的問題。UTF-16以兩個(gè)字節(jié)為編碼單元淳玩,在解釋一個(gè)UTF-16文本前直撤,首先要弄清楚每個(gè)編碼單元的字節(jié)序。例如收到一個(gè)“奎”的Unicode編碼是594E蜕着,“乙”的Unicode編碼是4E59谋竖。如果我們收到UTF-16字節(jié)流“594E”,那么這是“奎”還是“乙”侮东?

Unicode規(guī)范中推薦的標(biāo)記字節(jié)順序的方法是BOM圈盔。BOM是Byte Order Mark杭跪。BOM是一個(gè)有點(diǎn)小聰明的想法:
在UCS編碼中有一個(gè)叫做"ZERO WIDTH NO-BREAK SPACE"的字符琅捏,它的編碼是FEFF愤兵。而FFFE在UCS中是不存在的字符,所以不應(yīng)該出現(xiàn)在實(shí)際傳輸中宽闲。UCS規(guī)范建議我們?cè)趥鬏斪止?jié)流前,先傳輸字符"ZERO WIDTHNO-BREAK SPACE"握牧。
這樣如果接收者收到FEFF容诬,就表明這個(gè)字節(jié)流是Big-Endian的;如果收到FFFE沿腰,就表明這個(gè)字節(jié)流是Little-Endian的览徒。因此字符" zero widthno-break space"又被稱作BOM。

UTF-8不需要BOM來表明字節(jié)順序颂龙,但可以用BOM來表明編碼方式习蓬。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF(讀者可以用我們前面介紹的編碼方法驗(yàn)證一下)。所以如果接收者收到以EF BB BF開頭的字節(jié)流措嵌,就知道這是UTF-8編碼了躲叼。

9、Windows記事本有四種保存格式

用記事本-文件-另存為企巢,如上如圖即可看到Windows記事本保存的四種格式枫慷,如上如所示,分別為:
ANSI:在簡(jiǎn)體中文系統(tǒng)的windows中ANSI即gb2312.
Unicode:對(duì)應(yīng)UTF-16LE,
Unicode Big Endian:對(duì)應(yīng)UTF-16BE
UTF-8:使用了變長(zhǎng)的編碼

Big Endian 和 Little Endian名詞的由來
這兩個(gè)術(shù)語來自于 Jonathan Swift 的《《格利佛游記》其中交戰(zhàn)的兩個(gè)派別無法就應(yīng)該從哪一端--小端還是大端--打開一個(gè)半熟的雞蛋達(dá)成一致或听。:)
“endian”這個(gè)詞出自《格列佛游記》探孝。小人國的內(nèi)戰(zhàn)就源于吃雞蛋時(shí)是究竟從大頭(Big-Endian)敲開還是從小頭(Little-Endian)敲開,由此曾發(fā)生過六次叛亂誉裆,其中一個(gè)皇帝送了命再姑,另一個(gè)丟了王位。
我們一般將endian翻譯成“字節(jié)序”找御,將big endian和little endian稱作“大尾”和“小尾”元镀。
在那個(gè)時(shí)代,Swift是在諷刺英國和法國之間的持續(xù)沖突霎桅,Danny Cohen栖疑,一位網(wǎng)絡(luò)協(xié)議的早期開創(chuàng)者,第一次使用這兩個(gè)術(shù)語來指代字節(jié)順序滔驶,后來這個(gè)術(shù)語被廣泛接納了遇革。
主要表現(xiàn)在存儲(chǔ)格式上,比如一個(gè)字符的編碼為ABCD
Big Endian的(FE FF)存儲(chǔ)格式為:AB CD揭糕;
Little Endian的(FF FE)存儲(chǔ)格式為:CD AB 萝快;
Windows記事本就是使用BOM來標(biāo)記文本文件的編碼方式的。當(dāng)打開一個(gè)txt文本著角,會(huì)自動(dòng)添加BOM揪漩。

二 應(yīng)用

  1. 1 Java對(duì)字符的處理
    1 )、String類的public byte[] getBytes(Charset charset) 這是java字符串處理的一個(gè)標(biāo)準(zhǔn)函數(shù)吏口,其作用是將字符串所表示的字符按照charset編碼奄容,并以字節(jié)方式表示。注意字符串在java內(nèi)存中總是按unicode編碼存儲(chǔ)的产徊。
public class Test1 {  
    public static void main(String[] args) throws Exception {  
       String string = "你好昂勒!";  
       String str1 = new String(string.getBytes("gbk"));  
       System.out.println(str1);  
    }  
}  

將一個(gè)String 類型Unicode字符串轉(zhuǎn)為對(duì)應(yīng)字節(jié),一般String默認(rèn)光標(biāo)gbk編碼舟铜;各個(gè)編譯器可能不同戈盈,可以到windows-preference-general-workspace界面的左下角有顯示,也可以自行調(diào)節(jié)谆刨。

2)塘娶、 new String(charset)
這是java字符串處理的另一個(gè)標(biāo)準(zhǔn)函數(shù),和上一個(gè)函數(shù)的作用相反痴荐,將字節(jié)數(shù)組按照charset編碼進(jìn)行組合識(shí)別血柳,最后轉(zhuǎn)換為unicode存儲(chǔ)。參考上述getBytes的例子

3)生兆、setCharacterEncoding()
該函數(shù)用來設(shè)置http請(qǐng)求或者相應(yīng)的編碼难捌。

1.2. String 與byte的相互轉(zhuǎn)換
java字符編碼常見問題主要在兩個(gè)方面

  • 字節(jié)到String
  • String轉(zhuǎn)字節(jié)膝宁。

1.2.1 字節(jié)到String。
只有字節(jié)才有編碼含義根吁,String永遠(yuǎn)是Unicode员淫。在java中,字符默認(rèn)存儲(chǔ)的編碼為utf-8碼击敌,所以String str1 = “你好介返,Ice Blue”;Str的編碼為utf-8可以用一下代碼來實(shí)驗(yàn):

System.out.println(Charset.defaultCharset());

以下java代碼實(shí)現(xiàn)了將一個(gè)字符的編碼轉(zhuǎn)換為漢字。

public class Test02 {  
   public static void main(String[] args) throws Exception {  
      System.out.println("字節(jié)按編碼轉(zhuǎn)成字符:");  
      String strUtf8Hex = "E4B8ADE69687"; // “中文”的utf8的16進(jìn)制編碼  
      byte byteUtf8[] = hex2byte(strUtf8Hex);// 轉(zhuǎn)成字節(jié)流  
   
      String str = new String(byteUtf8,"UTF-8");  
      System.out.println(str);  
   }  
   
   public static byte[] hex2byte(String str) {  
      byte[] b = new byte[str.length() / 2];  
      for (inti = 0; i < str.length(); i += 2) {  
         String str2 = str.substring(i, i + 2);  
         b[i / 2] = (byte) Integer.parseInt(str2, 16);  
      }  
      return b;  
   }  
}  

2. String轉(zhuǎn)字節(jié)沃斤。String.getBytes方法是按編碼集轉(zhuǎn)換編碼圣蝎,不能理解為取出String的字節(jié)來。是平時(shí)常見轉(zhuǎn)碼工作應(yīng)該采用的方法衡瓶。
以下代碼實(shí)現(xiàn)了將一個(gè)漢字轉(zhuǎn)換為其對(duì)應(yīng)編碼

public class Test1 {  
   public static void main(String[]args) throws Exception {  
      System.out.println("字節(jié)按編碼轉(zhuǎn)成字符:");  
      String strUtf8Hex ="中文賦";// “中文”的utf8的16進(jìn)制編碼  
      byte[] Utf8byte = strUtf8Hex.getBytes("UTF-16BE");  
      System.out.println(byte2hex(Utf8byte));  
   }  
   
   public static String byte2hex(byte[]b) {  
      String sum = "";  
      String stmp = "";  
      for (inti = 0; i < b.length; i++) {  
         stmp = Integer.toHexString(b[i] & 0XFF);//保留前8位  
         if (stmp.length() == 1)  
            sum = sum + "0" + stmp;  
         else  
            sum = sum + stmp;  
      }  
      return sum.toUpperCase();  
   }  
}  

拓展:

計(jì)算機(jī)數(shù)制的概念
基本概念:
數(shù)碼數(shù)制中表示基本數(shù)值大小的不同數(shù)字符號(hào)徘公。
例如,
二進(jìn)制有兩個(gè)數(shù)碼:0,1哮针;
十進(jìn)制有10個(gè)數(shù)碼:0关面、1、2十厢、3等太、4、5蛮放、6缩抡、7、8筛武、9缝其。
十六進(jìn)制有16個(gè)數(shù)碼:0挎塌、1徘六、2、3榴都、4待锈、5、6嘴高、7竿音、8、9拴驮,A春瞬、B、C套啤、D宽气、E、F

基數(shù):數(shù)制所使用數(shù)碼的個(gè)數(shù)。例如萄涯,二進(jìn)制的基數(shù)為2绪氛;十進(jìn)制的基數(shù)為10。****
位權(quán): 數(shù)制中某一位上的1所表示數(shù)值的大欣杂啊(所處位置的價(jià)值)枣察。例如,十進(jìn)制的123燃逻,1的位權(quán)是100序目,2的位權(quán)是10,3的位權(quán)是1伯襟。二進(jìn)制中的 1011 宛琅,第一個(gè)1的位權(quán)是8,0的位權(quán)是4逗旁,第二個(gè)1的位權(quán)是2嘿辟,第三個(gè)1的位權(quán)是1;
數(shù)制:按進(jìn)位的原則進(jìn)行計(jì)數(shù)片效,稱為進(jìn)位計(jì)數(shù)制红伦,簡(jiǎn)稱數(shù)制。不論是哪一種數(shù)制淀衣,其計(jì)數(shù)和運(yùn)算都有共同的規(guī)律和特點(diǎn)昙读。
⑴ ** 逢N進(jìn)一

N是指數(shù)制中所需要的數(shù)字字符的總個(gè)數(shù),稱為基數(shù)膨桥。如:0蛮浑、1、2只嚣、3沮稚、4、5册舞、6蕴掏、7、8调鲸、9等10個(gè)不同的符號(hào)來表示數(shù)值盛杰,這個(gè)10就是數(shù)字字符的總個(gè)數(shù),也是十進(jìn)制的基數(shù)藐石,表示逢十進(jìn)一即供。
⑵ ** 位權(quán)表示法

位權(quán)是指一個(gè)數(shù)字在某個(gè)固定位置上所代表的值,處在不同位置上的數(shù)字所代表的值不同于微,每個(gè)數(shù)字的位置決定了它的值或者位權(quán)逗嫡。位權(quán)與基數(shù)的關(guān)系是:各進(jìn)位制中位權(quán)的值是基數(shù)的若干次冪办素。

數(shù)制符號(hào)
二進(jìn)制B(binary)
八進(jìn)制O(octal)
十進(jìn)制D(decimal)
十六進(jìn)制H(hexadecimal)

至于進(jìn)制轉(zhuǎn)換網(wǎng)上有很多參考文檔,這里不再贅述祸穷。

參考資料:
[1] 趣談Unicode性穿,ansi,utf-8,Unicode big endian這些編碼有什么區(qū)別(http://blog.csdn.net/fanwenbo/article/details/2298800
[2] Unicode字符查詢(http://unicode-table.com/cn/#control-character
[3] 國標(biāo)碼查詢 (http://www.qqxiuzi.cn/bianma/guobiaoma.php
[4] Code Page Identifiers ( https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx
[5] UTF-16與UCS-2的區(qū)別 http://demon.tw/programming/utf-16-ucs-2.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末雷滚,一起剝皮案震驚了整個(gè)濱河市需曾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祈远,老刑警劉巖呆万,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異车份,居然都是意外死亡谋减,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門扫沼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來出爹,“玉大人,你說我怎么就攤上這事缎除⊙暇停” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵器罐,是天一觀的道長(zhǎng)梢为。 經(jīng)常有香客問我,道長(zhǎng)轰坊,這世上最難降的妖魔是什么铸董? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮肴沫,結(jié)果婚禮上粟害,老公的妹妹穿的比我還像新娘。我一直安慰自己樊零,他們只是感情好我磁,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著驻襟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪芋哭。 梳的紋絲不亂的頭發(fā)上沉衣,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音减牺,去河邊找鬼豌习。 笑死存谎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的肥隆。 我是一名探鬼主播既荚,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼栋艳!你這毒婦竟也來了恰聘?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤吸占,失蹤者是張志新(化名)和其女友劉穎晴叨,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體矾屯,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡兼蕊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了件蚕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片孙技。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖排作,靈堂內(nèi)的尸體忽然破棺而出绪杏,到底是詐尸還是另有隱情,我是刑警寧澤纽绍,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布蕾久,位于F島的核電站,受9級(jí)特大地震影響拌夏,放射性物質(zhì)發(fā)生泄漏僧著。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一障簿、第九天 我趴在偏房一處隱蔽的房頂上張望盹愚。 院中可真熱鬧,春花似錦站故、人聲如沸皆怕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽愈腾。三九已至,卻和暖如春岂津,著一層夾襖步出監(jiān)牢的瞬間虱黄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來泰國打工吮成, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留橱乱,地道東北人辜梳。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像泳叠,于是被迫代替她去往敵國和親作瞄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1. ASCII ??我們知道属韧,計(jì)算機(jī)內(nèi)部是通過二進(jìn)制數(shù)據(jù)進(jìn)行操作的,所有的信息最終都會(huì)轉(zhuǎn)換為一個(gè)二進(jìn)制值蛤吓,二進(jìn)制...
    騎著烏龜去看海閱讀 1,636評(píng)論 0 4
  • UTF-8 編碼提供了一種簡(jiǎn)便而向后兼容的方法, 使得那種完全圍繞 ASCII 設(shè)計(jì)的操作系統(tǒng), 比如 Unix,...
    謝大見閱讀 4,665評(píng)論 0 3
  • 騰訊大講堂——字符編碼的前世今生字符串宵喂,那些你不知道的事編碼字符集標(biāo)準(zhǔn)及分類研究通信用語の基礎(chǔ)知識(shí) —— ISO/...
    AItsuki閱讀 1,399評(píng)論 0 4
  • 今天有一個(gè)很好的消息 一早上迷迷糊糊查教資 居然通過了最后的面試 好像離目標(biāo)又近了一點(diǎn) 還有就是我發(fā)現(xiàn)一件事 遇到...
    Suki芝閱讀 119評(píng)論 0 3
  • 父母是孩子最貼心、最直接的護(hù)航者会傲,對(duì)孩子一生的發(fā)展都有著極為深遠(yuǎn)的影響锅棕。在親子關(guān)系中,父母和孩子溝通無論采用什么樣...
    Yin愛麗絲閱讀 170評(píng)論 0 6