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編碼簡單點(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è)簡體漢字了。在這些編碼里,我們還把數(shù)學(xué)符號(hào)、羅馬希臘的字母、日文的假名們都編進(jìn)去了,連在 ASCII 里本來就有的數(shù)字、標(biāo)點(diǎn)、字母都統(tǒng)統(tǒng)重新編了兩個(gè)字節(jié)長的編碼,這就是常說的"全角"字符,而原來在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字符集可以簡寫為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)是一種定長的編碼方式,UCS-2僅僅簡單的使用一個(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è)字符。
簡單的說,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 簡體中文 (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)是一種定長的編碼方式,UCS-2僅僅簡的使用一個(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è)字符。

簡單的說,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:在簡體中文系統(tǒng)的windows中ANSI即gb2312.
Unicode:對(duì)應(yīng)UTF-16LE,
Unicode Big Endian:對(duì)應(yīng)UTF-16BE
UTF-8:使用了變長的編碼

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ù)制,簡稱數(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)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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