Java字元編碼的轉化問題

來源:互聯網
上載者:User

標籤:center   style   utf-8   app   csdn   except   產生   continue   系統   

概述:

  我想字串的編碼問題的確會困擾到非常多開發人員。我近期也是被困擾到了。

  問題是這種,我們通過二維碼掃描來獲得二維碼中的資訊。可是。我們的二維碼的產生過程卻是“多樣化”的。即在產生二維碼的時候是以不同的字串編碼類別型進行編碼的。比方,GBK、GB2312、UTF-8等等。而這些不同的編碼類別型會產生不同的位元組。在Java中。GBK和GB2312都是1個漢字佔2個位元組,UTF-8是1個漢字佔3個位元組。而ISO編碼則是1上漢字1個位元組。這樣一來,我們在掃描二維碼的時候就會出現一些“陰陽怪氣”的亂碼字元。

  這裡我們是開發二維的掃描。而二維碼的產生則在來自不同的產商。


我的前期實驗:

  系統字元格式設定:UTF-8

  字串"中國"的GB2312編碼位元組數組bs_gb和UTF-8編碼位元組數組bs_utf
    byte[] bs_gb = {-42, -48, -71, -6};
    byte[] bs_utf = {-28, -72, -83, -27, -101, -67};


  實驗步驟:

    1.首先對bs_gb分別使用GB2312編碼和UTF-8編碼轉化為一個中間結果:
      String gbStr1 = new String(bs_gb, "GB2312");
      String utfStr1 = new String(bs_gb, "UTF-8");
      結果:
      中國
      ?й?




    2.對utfStr1進行GB2312編碼,實現從 GB2312編碼 -> UTF-8編碼 -> GB2312編碼 的過程
      String gbStr2 = new String(utfStr1.getBytes("UTF-8"), "GB2312");
      結果:錕叫癸拷
  
    3.對bs_utf分別使用GB2312編碼和UTF-8編碼轉化為一個中間結果:
      String gbStr3 = new String(bs_utf, "GB2312");
      String utfStr2 = new String(bs_utf, "UTF-8");
      結果:
      涓??


      中國
  
    4.對gbStr3進行UTF-8編碼,實現從 UTF-8編碼 -> GB2312編碼 -> UTF-8編碼 的過程
      String utfStr3 = new String(gbStr3.getBytes("GB2312"), "UTF-8");
      結果:
      ??

?


  
    5.根據上面4個步驟。進行GBK和UTF-8之間的轉換實驗


    實驗的初步結論:

      UTF-8編碼和GB2312編碼之間不能進行直接轉化
      UTF-8編碼和GBK編碼之間,僅僅能是UTF-8 -> GBK -> UTF-8


不同編碼字元之間的轉化:

  UTF-8轉化為Unicode

private static final char[] hexDigit = {‘0‘,‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,‘6‘,‘7‘,‘8‘,‘9‘,‘A‘,‘B‘,‘C‘,‘D‘,‘E‘,‘F‘};    private static char toHex(int nibble) {return hexDigit[(nibble & 0xF)];}/**     * 將字串編碼成 Unicode。     * @param theString 待轉換成Unicode編碼的字串。

* @param escapeSpace 是否忽略空格 * @return 返迴轉換後Unicode編碼的字串。

*/ public static String toUnicode(String theString, boolean escapeSpace) { int len = theString.length();int bufLen = len * 2; if (bufLen < 0) { bufLen = Integer.MAX_VALUE;} StringBuffer outBuffer = new StringBuffer(bufLen); for(int x=0; x<len; x++) { char aChar = theString.charAt(x); // Handle common case first, selecting largest block that// avoids the specials below if ((aChar > 61) && (aChar < 127)) {if (aChar == ‘\\‘) { outBuffer.append(‘\\‘); outBuffer.append(‘\\‘);continue;} outBuffer.append(aChar);continue;} switch(aChar) {case ‘ ‘: if (x == 0 || escapeSpace)outBuffer.append(‘\\‘);outBuffer.append(‘ ‘);break; case ‘\t‘:outBuffer.append(‘\\‘);outBuffer.append(‘t‘);break; case ‘\n‘:outBuffer.append(‘\\‘);outBuffer.append(‘n‘);break; case ‘\r‘:outBuffer.append(‘\\‘);outBuffer.append(‘r‘);break; case ‘\f‘:outBuffer.append(‘\\‘);outBuffer.append(‘f‘);break; case ‘=‘: // Fall through case ‘:‘: // Fall through case ‘#‘: // Fall through case ‘!‘: outBuffer.append(‘\\‘);outBuffer.append(aChar);break;default: if ((aChar < 0x0020) || (aChar > 0x007e)) {outBuffer.append(‘\\‘);outBuffer.append(‘u‘); outBuffer.append(toHex((aChar >> 12) & 0xF));outBuffer.append(toHex((aChar >> 8) & 0xF));outBuffer.append(toHex((aChar >> 4) & 0xF)); outBuffer.append(toHex( aChar & 0xF));} else { outBuffer.append(aChar);}}} return outBuffer.toString();}


  Unicode轉化為UTF-8

/** * unicode 轉換成 utf-8 *  * @param theString * @return */public static String unicodeToUtf8(String theString) {char aChar;int len = theString.length();StringBuffer outBuffer = new StringBuffer(len);for (int x = 0; x < len;) {aChar = theString.charAt(x++);if (aChar == ‘\\‘) {aChar = theString.charAt(x++);if (aChar == ‘u‘) {// Read the xxxxint value = 0;for (int i = 0; i < 4; i++) {aChar = theString.charAt(x++);switch (aChar) {case ‘0‘:case ‘1‘:case ‘2‘:case ‘3‘:case ‘4‘:case ‘5‘:case ‘6‘:case ‘7‘:case ‘8‘:case ‘9‘:value = (value << 4) + aChar - ‘0‘;break;case ‘a‘:case ‘b‘:case ‘c‘:case ‘d‘:case ‘e‘:case ‘f‘:value = (value << 4) + 10 + aChar - ‘a‘;break;case ‘A‘:case ‘B‘:case ‘C‘:case ‘D‘:case ‘E‘:case ‘F‘:value = (value << 4) + 10 + aChar - ‘A‘;break;default:throw new IllegalArgumentException("Malformed   \\uxxxx   encoding.");}}outBuffer.append((char) value);} else {if (aChar == ‘t‘)aChar = ‘\t‘;else if (aChar == ‘r‘)aChar = ‘\r‘;else if (aChar == ‘n‘)aChar = ‘\n‘;else if (aChar == ‘f‘)aChar = ‘\f‘;outBuffer.append(aChar);}} elseoutBuffer.append(aChar);}return outBuffer.toString();}

  而對於其GB2312的編碼格式是不能夠在獲得一個字串之後再轉化成其它的編碼格式的。

比方,我的一個字串為“中國”,我把它轉成GB2312的編碼格式為:涓??,再轉成UTF-8就變成了??

?

  只是還好,對於經過GBK和ISO-8859-1這兩種格式編碼之後的字元,再進行UTF-8的轉化,是能夠轉換回來的。例如以下測試:

  

  結果:

  

Java字元編碼的轉化問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.