一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

正確理解UNICODE UTF

 網(wǎng)文收集 2012-04-16

正確理解UNICODE UTF-8等編碼方式

分類: 綜合 2315人閱讀 評(píng)論(1) 收藏 舉報(bào)

如果你開發(fā)過的軟件項(xiàng)目中涉及到多語言支持的問題,那么相信你沒少碰到過亂碼問題,然后在尋求解決問題的途徑過程中被一些概念如ASCII, ISO-8859-1, Unicode,UTF-8,GBK,GB2312等等所困擾。本文有助于你正確的理解這些概念。

1. ASCII

7位編碼將英文字符和一些常用的符號(hào)存諸為從0127的數(shù)值。

 

2. ISO-8859-1

法語、西班牙語和德語之類的西歐語言都使用叫做ISO-8859-1的編碼系統(tǒng)(也叫做“latin-1”)。它使用7ASCII字符表示從0127的字符,但接著擴(kuò)展到了128-255的范圍來表示如n上帶有一個(gè)波浪線(241),和u上帶有兩個(gè)點(diǎn)(252)的字符等等??梢哉fASCIIISO-8859-1的子集。

 

3. Unicode

    Unicode用一個(gè)2字節(jié)數(shù)字表示每個(gè)字符,從065535。每個(gè) 2 字節(jié)數(shù)字表示至少在一種世界語言中使用的一個(gè)唯一字符。(在多種語言中都使用的字符具有相同的數(shù)字碼。)這樣就確保每個(gè)字符一個(gè)數(shù)字,并且每個(gè)數(shù)字一個(gè)字符。Unicode數(shù)據(jù)永遠(yuǎn)不會(huì)模棱兩可。Unicode使用相同的數(shù)字表示ASCIIISO-8859-1中的字符。只是這兩種編碼用一個(gè)字節(jié)表示,而Unicode用兩個(gè)字節(jié)表示。所以Unicode表示這兩種編碼的字符時(shí)只要用低字節(jié)就可以了,高字節(jié)為0。

 

4. UTF-8

    UTF-8是一種變長(zhǎng)的編碼方式,每個(gè)UTF-8的編碼可以是16個(gè)字節(jié)長(zhǎng)。它將Unicode編碼的字符采用變長(zhǎng)的方式進(jìn)行編碼。對(duì)Unicode中屬于ISO-8859-1的編碼采用和ISO-8859-1相同的單字節(jié)編碼。其他字符采用兩字節(jié)以上的編碼。實(shí)際上對(duì)于兩個(gè)字節(jié)的Unicode編碼,UTF-8只要三個(gè)字節(jié)即可表示。第一個(gè)字節(jié)由n個(gè)11< n <= 6)開始, n表示編碼的字節(jié)數(shù),后面每個(gè)字節(jié)都以10開始,后面6位為有效位。將第一位的剩余位和后面的所有字節(jié)的后六位連接起來就是對(duì)應(yīng)的Unicode編碼的數(shù)值。例如漢字“中”的編碼:

 

Unicode:           4E      2D

01001110 00101101

 

UTF-8:              E4      B8     AD

11100100 10111000 10101101

 

可以通過以下方式進(jìn)行證實(shí):

       用記事本創(chuàng)建一個(gè)文本文件,輸入漢字“中”分別保存為Unicode格式和UTF-8格式。 UltraEdit的自動(dòng)識(shí)別UTF-8文件格式選項(xiàng)禁止,然后用其打開這兩個(gè)文件,選用二進(jìn)制查看方式,可以看到:

    UTF-8格式文件編碼為“EF BB BF E4 B8 AD”。其中有個(gè)三字節(jié)的前綴“EF BB BF”,這是UTF-8格式文本文件的標(biāo)識(shí)。不過這個(gè)前綴不要,某些文本查看軟件也可以通過編碼判斷出UTF-8格式。“E4 B8 AD”就是“中”的UTF-8編碼。

    Unicode格式的文件的完整編碼是“FF FE 2D 4E”。前面有個(gè)雙字節(jié)前綴“FF FE”,這是Unicode格式文本文檔的編碼標(biāo)識(shí)。而我們看到的編碼是“2D 4E”,而不是如我前面所說的“4E 2D”,為什么呢?因?yàn)閿?shù)字是按照低字節(jié)在先高字節(jié)在后的順序存儲(chǔ)的,所以實(shí)際的Unicode編碼恰恰是“4E2D”。

 

5. GB2312GBK

       這兩種編碼都是漢字的編碼標(biāo)準(zhǔn),其中前者是后者的子集。GBK編碼的文本文檔中對(duì)于ASCII中的字符用相同的單字節(jié)表示;對(duì)于漢字和漢語中的標(biāo)點(diǎn)符號(hào)等采用雙字節(jié)編碼,其中高字節(jié)大于0x80,而ASCII的所有字符的編碼均小于0x80, 所以ASCIIGBK的字符是可以混和起來的。GBK的字符集和Unicode進(jìn)行轉(zhuǎn)換是無規(guī)則的,需要轉(zhuǎn)換表才能進(jìn)行轉(zhuǎn)換。

 

6.下面給出我用Java語言寫的UnicodeUTF-8轉(zhuǎn)換的程序片段,供大家參考。

 

因?yàn)?/span>Java語言的字符使用Unicode編碼的,所以程序中是對(duì)UTF-8編碼的字符串的字節(jié)數(shù)組和JavaString類型進(jìn)行轉(zhuǎn)換。String對(duì)象中的每一個(gè)Character就是一個(gè)Unicode編碼的字符。

 

public String utf8Bytes2String(byte[] buff){

              if(buff == null)

                     return null;

             

              StringBuffer sb = new StringBuffer();

             

              int idx = 0;

             

              if(buff[0] == (byte)0xEF &&

                            buff[1] == (byte)0xBB &&

                            buff[2] == (byte)0xBF)

                     idx = 3;//Skip UTF8 header

 

              while(idx < buff.length){

                     int hB = buff[idx] & 0xFF;

                     int bCnt = 0;

                     int check = 0x80;

                     for(int i=0; i<8; i++){

                            if((hB & check) != 0){

                                   bCnt ++;

                                   check >>= 1;

                            }else

                                   break;

                     }

                    

                     if(bCnt <= 1){

                            char c = 0;

                            c |= buff[idx] & 0xFF;

                            sb.append(c);

                            idx++;

                     }else if(bCnt == 2){

                            char c = 0;

                            c |= buff[idx] & 0x03;

                            c <<= 6;

                            if((buff[idx+1] & 0xC0) != 0x80)

                                   return null;

                            c |= buff[idx+1] & 0x3F;

                            idx += 2;

                            sb.append(c);

                     }else if(bCnt == 3){

                            char c = 0;

                            c |= buff[idx] & 0x0F;

                            c <<= 6;

                            if((buff[idx+1] & 0xC0) != 0x80)

                                   return null;

                            c |= buff[idx+1] & 0x3F;

                            c <<= 6;

                            if((buff[idx+2] & 0xC0) != 0x80)

                                   return null;

                            c |= buff[idx+2] & 0x3F;

                            idx += 3;

                            sb.append(c);

                     }else

                            return null;

              }

             

              return sb.toString();

       }

      

       public byte[] string2Utf8Bytes(String str){

              if(str == null)

                     return null;

             

              ByteArrayOutputStream bos = new ByteArrayOutputStream();

              try {

                     string2Utf8Stream(str, bos);

              } catch (IOException e) {

                     e.printStackTrace();

              }

              return bos.toByteArray();

       }

 

public void string2Utf8Stream(String str, OutputStream os) throws IOException {

              if(str == null || os == null)

                     return;

             

              for(int i=0; i<str.length(); i++){

                     char c = str.charAt(i);

                     if(c < 0x80){

                            os.write((byte)c);

                     }else if(c >=0x80 && c < 0x100){

                            int hi = c >> 6;

                            hi |= 0xC0;

                            int lo = c & 0x3F;

                            lo |= 0x80;

                            os.write(hi);

                            os.write(lo);

                     }else{

                            int first = c >> 12;

                            first |= 0xE0;

                            int second = c >> 6;

                            second &= 0x3F;

                            second |= 0x80;

                            int third = c & 0x3F;

                            third |= 0x80;

                            os.write(first);

                            os.write(second);

                            os.write(third);

                     }

              }

       }

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    神马午夜福利免费视频| 欧美不卡一区二区在线视频| 插进她的身体里在线观看骚| 东京热一二三区在线免| 亚洲高清亚洲欧美一区二区| 亚洲精品欧美精品一区三区| 精品al亚洲麻豆一区| 亚洲丁香婷婷久久一区| 91麻豆视频国产一区二区| 国产亚洲中文日韩欧美综合网| 国产精品丝袜美腿一区二区| 欧美日韩人妻中文一区二区| 色婷婷视频国产一区视频| 麻豆视传媒短视频免费观看| 久久精品国产第一区二区三区| 噜噜中文字幕一区二区| 欧美成人精品一区二区久久| 亚洲人午夜精品射精日韩| 五月天丁香亚洲综合网| 九九热最新视频免费观看| 青青操成人免费在线视频| 国产精品欧美一区二区三区不卡 | 99久久精品午夜一区二区| 亚洲熟女国产熟女二区三区| 午夜传媒视频免费在线观看| 国产传媒一区二区三区| 亚洲中文字幕高清乱码毛片| 亚洲综合色婷婷七月丁香| 国产日韩欧美国产欧美日韩 | 果冻传媒精选麻豆白晶晶 | 国语久精品在视频在线观看| 日本加勒比不卡二三四区| 国产在线观看不卡一区二区| 在线观看视频国产你懂的| 国产精品一区二区传媒蜜臀| 美国欧洲日本韩国二本道| 少妇人妻中出中文字幕| 久久精品国产熟女精品| 国产三级视频不卡在线观看| 日韩在线视频精品中文字幕| 91人妻久久精品一区二区三区|