解决GBK字符转UTF-8乱码问题

时间:2023-01-06 12:54:05

gbk转utf-8,奇数中文乱码。

一、乱码的原因

gbk的中文编码是一个汉字用【2】个字节表示,例如汉字“内部”的gbk编码16进制的显示为c4 da b2 bf

utf-8的中文编码是一个汉字用【3】个字节表示,例如汉字“内部”的utf-8编码16进制的显示为e5 86 85 e9 83 a8

很显然,gbk是无法直接转换成utf-8,少字节变为多字节

二、转换的办法

1.首先将gbk字符串getBytes()得到两个原始字节,转换成二进制字符流,共16位。

2.根据UTF-8的汉字编码规则,首字节以1110开头,次字节以10开头,第3字节以10开头。在原始的2进制字符串中插入标志位。最终的长度从16--->16+3+2+2=24。

3.转换完成

 

通过以下方法将GBK字符转成UTF-8编码格式的byte【】数组

  1. package test;  
  2.   
  3. import java.io.UnsupportedEncodingException;  
  4.   
  5. public class TestEncoder {  
  6.   
  7.     /** 
  8.      * @param args 
  9.      */  
  10.     public static void main(String[] args) throws Exception {  
  11.         String gbk = "iteye问答频道编码转换问题";  
  12.           
  13.         String iso = new String(gbk.getBytes("UTF-8"),"ISO-8859-1");   
  14.   
  15.         System.out.println(iso);  
  16.           
  17.         String utf8 = new String(iso.getBytes("ISO-8859-1"),"UTF-8");  
  18.         System.out.println(utf8);  
  19.           
  20.         System.out.println(getUTF8StringFromGBKString(gbk));  
  21.     }  
  22.   
  23.     public static String getUTF8StringFromGBKString(String gbkStr) {  
  24.         try {  
  25.             return new String(getUTF8BytesFromGBKString(gbkStr), "UTF-8");  
  26.         } catch (UnsupportedEncodingException e) {  
  27.             throw new InternalError();  
  28.         }  
  29.     }  
  30.       
  31.     public static byte[] getUTF8BytesFromGBKString(String gbkStr) {  
  32.         int n = gbkStr.length();  
  33.         byte[] utfBytes = new byte[3 * n];  
  34.         int k = 0;  
  35.         for (int i = 0; i < n; i++) {  
  36.             int m = gbkStr.charAt(i);  
  37.             if (m < 128 && m >= 0) {  
  38.                 utfBytes[k++] = (byte) m;  
  39.                 continue;  
  40.             }  
  41.             utfBytes[k++] = (byte) (0xe0 | (m >> 12));  
  42.             utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f));  
  43.             utfBytes[k++] = (byte) (0x80 | (m & 0x3f));  
  44.         }  
  45.         if (k < utfBytes.length) {  
  46.             byte[] tmp = new byte[k];  
  47.             System.arraycopy(utfBytes, 0, tmp, 0, k);  
  48.             return tmp;  
  49.         }  
  50.         return utfBytes;  
  51.     }  

或者:

  1. public static void gbk2Utf() throws UnsupportedEncodingException {  
  2.     String gbk = "我来了";  
  3.     char[] c = gbk.toCharArray();  
  4.     byte[] fullByte = new byte[3*c.length];  
  5.     for (int i=0; i<c.length; i++) {  
  6.         String binary = Integer.toBinaryString(c[i]);  
  7.         StringBuffer sb = new StringBuffer();  
  8.         int len = 16 - binary.length();  
  9.         //前面补零  
  10.         for(int j=0; j<len; j++){  
  11.                 sb.append("0");  
  12.             }  
  13.         sb.append(binary);  
  14.         //增加位,达到到24位3个字节  
  15.         sb.insert(0, "1110");  
  16.             sb.insert(8, "10");  
  17.             sb.insert(16, "10");  
  18.             fullByte[i*3] = Integer.valueOf(sb.substring(0, 8), 2).byteValue();//二进制字符串创建整型  
  19.             fullByte[i*3+1] = Integer.valueOf(sb.substring(8, 16), 2).byteValue();  
  20.             fullByte[i*3+2] = Integer.valueOf(sb.substring(16, 24), 2).byteValue();  
  21.     }  
  22.     //模拟UTF-8编码的网站显示  
  23.     System.out.println(new String(fullByte,"UTF-8"));