java版字符串编码转换

来源:互联网 发布:网络销售的工资 编辑:程序博客网 时间:2024/06/05 14:27
import java.lang.Character.UnicodeBlock;/** * Created by Administrator on 2016/1/14. */public class CharsetUtil {    public static void main(String[] args){        String str="天空很蓝,大海很咸,顺远";        String unicode=GBK2Unicode(str);        System.out.println(unicode);        String utf=unicodeToUtf8(unicode);        System.out.println(utf);        unicode=utf8ToUnicode(str);        utf=unicodeToUtf8(unicode);        System.out.println(utf);    }    public static String gbk2utf8(String gbk) {        String l_temp = GBK2Unicode(gbk);        l_temp = unicodeToUtf8(l_temp);        return l_temp;    }    public static String utf82gbk(String utf) {        String l_temp = utf8ToUnicode(utf);        l_temp = Unicode2GBK(l_temp);        return l_temp;    }    /**     *     * @param str     * @return String     */    public static String GBK2Unicode(String str) {        StringBuffer result = new StringBuffer();        for (int i = 0; i < str.length(); i++) {            char chr1 = (char) str.charAt(i);            if (!isNeedConvert(chr1)) {                result.append(chr1);                continue;            }            result.append("\\u" + Integer.toHexString((int) chr1));        }        return result.toString();    }    /**     *     * @param dataStr     * @return String     */    public static String Unicode2GBK(String dataStr) {        int index = 0;        StringBuffer buffer = new StringBuffer();        int li_len = dataStr.length();        while (index < li_len) {            if (index >= li_len - 1                    || !"\\u".equals(dataStr.substring(index, index + 2))) {                buffer.append(dataStr.charAt(index));                index++;                continue;            }            String charStr = "";            charStr = dataStr.substring(index + 2, index + 6);            char letter = (char) Integer.parseInt(charStr, 16);            buffer.append(letter);            index += 6;        }        return buffer.toString();    }    public static boolean isNeedConvert(char para) {        return ((para & (0x00FF)) != para);    }    /**     * utf-8 转unicode     *     * @param inStr     * @return String     */    public static String utf8ToUnicode(String inStr) {        char[] myBuffer = inStr.toCharArray();        StringBuffer sb = new StringBuffer();        for (int i = 0; i < inStr.length(); i++) {            UnicodeBlock ub = UnicodeBlock.of(myBuffer[i]);            if (ub == UnicodeBlock.BASIC_LATIN) {                sb.append(myBuffer[i]);            } else if (ub == UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {                int j = (int) myBuffer[i] - 65248;                sb.append((char) j);            } else {                int s = (int) myBuffer[i];                String hexS = Integer.toHexString(s);                String unicode = "\\u" + hexS;                sb.append(unicode.toLowerCase());            }        }        return sb.toString();    }    /**     *     * @param theString     * @return String     */    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 xxxx                    int 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);                }            } else                outBuffer.append(aChar);        }        return outBuffer.toString();    }}



还有一篇博客:http://blog.csdn.net/tge7618291/article/details/7608510


Unicode与GBK互转

3.1 GBK --> Unicode

Unicode 与 GBK 是两个完全不样的字符编码方案, 其两者没有直接关系, 要对其进行相
互转换, 最直接最高效的方法是查表.

GBK与Unicode的映射表可以从网上下载:
    http://www.gnu.org/directory/libiconv.html

显然, 只需要把下载下来的映射表用一个二维数组表示即可, tab_GBK_to_UCS2[i][0]表
示GBK编码值,  tab_GBK_to_UCS2[i][1]表示Unicode值.

[cpp] view plaincopy
  1. <span xmlns="http://www.w3.org/1999/xhtml" style="">// #c---  
  2. static const unsigned short tab_GBK_to_UCS2[][2] =  
  3. {  
  4.    /* GBK    Unicode     字 */  
  5.   
  6.     {0x8140, 0x4E02}, // 丂  
  7.     {0x8141, 0x4E04}, // 丄  
  8.     {0x8142, 0x4E05}, // 丅  
  9.     {0x8143, 0x4E06}, // 丆  
  10.     {0x8144, 0x4E0F}, // 丏  
  11.     ... ...  
  12.     {0x817F, 0x0001}, // XXXXX  
  13.     ... ...  
  14. };  
  15. // #c---end</span>  



但这有一个问题, 对于GBK编码并不是连续的, 有些编码目前是没有意义的, 如0x817F,
为了方便使用数组索引下标, 我们以把这些值也插入数组, 对应的Unicode值用一个不冲
突的值表示即可, 在这用的是0x0001. 这样对于任意的GBK编码值, 我们就可直接地利用
该数组直接找出其对应的Unicode编码值了. 起初, 我还打算用一个map来实现GBK到
Unicode 的转换, 这也只都是考虑到空间是否节省和是否高效. 对于高效, 数组当然没得
说; 用树实现的map也能达到log2; 用hash实现的map, 如果能选用效好的hash函数也是能
够达到常数级别的. 对于节省空间, 如果数据是连续的, 那是最理想不过了, 但目前这一
问题并不连续, 所以, 为了连续, 只能浪费点了, 算了下, 对于这一问题空间利用率为
69%左右; 如果是map, 因每个节点都要点空间, 所以算了一下, 其空间利用率也就67%左
右.


将一个字符的GBK编码转换成Unicode(UCS-2和UCS-4)编码.

[cpp] view plaincopy
  1. <span xmlns="http://www.w3.org/1999/xhtml" style="">// #c---  
  2. /***************************************************************************** 
  3.  * 将一个字符的GBK编码转换成Unicode(UCS-2和UCS-4)编码. 
  4.  * 
  5.  * 参数: 
  6.  *    gbk         字符的GBK编码值 
  7.  *    ucs         指向输出缓冲区, 其保存的数据即是Unicode编码值, 
  8.  *                类型为unsigned long . 
  9.  * 
  10.  * 返回值: 
  11.  *    1. 成功则返回该字符的GBK编码所占用的字节数; 
  12.  *         对于ASCII字符返回1, 对于非ASCII中文字符返回2. 
  13.  *    2. 失败则返回0. 
  14.  * 
  15.  * 注意: 
  16.  *     1. GBK 和 Unicode 都有字节序要求; 
  17.  *        字节序分为大端(Big Endian)和小端(Little Endian)两种; 
  18.  *        在Intel处理器中采用小端法表示, 在此采用小端法表示. (低地址存低位) 
  19.  ****************************************************************************/  
  20. int enc_GBK_to_unicode_one(unsigned short gbk,  
  21.         unsigned long *ucs)  
  22. {  
  23.     assert(ucs != NULL);  
  24.   
  25.     unsigned char *p = (unsigned char *) &gbk;  
  26.     unsigned char *phibyte = p + 1;  
  27.   
  28.     if ( *phibyte < 0x80 )  
  29.     {  
  30.         *ucs = *phibyte;  
  31.         return 1;  
  32.     }  
  33.     else  
  34.     {  
  35.         if ( gbk < tab_GBK_to_UCS2[0][0] ||  
  36.                 gbk > tab_GBK_to_UCS2[NUMOF_TAB_GBK_TO_UCS2 - 1][0] )  
  37.         {  
  38.             return 0;  
  39.         }  
  40.   
  41.         *ucs = tab_GBK_to_UCS2[gbk - tab_GBK_to_UCS2[0][0]][1];  
  42.     }  
  43.   
  44.     return 2;  
  45. }  
  46.   
  47. // #c---end  
  48.   
  49.   
  50. </span>  


3.2 Unicode --> GBK

要实现Unicode到GBK的转换, 可以使用以上的数组表结构, 但由于GBK对应的unicode值的
范围太广, 会造成很大的浪费, 空间利用率只有30%. 无奈只能用map了.

用hash实现的map是个不错的选择.

[cpp] view plaincopy
  1. <span xmlns="http://www.w3.org/1999/xhtml" style=""><span xmlns="http://www.w3.org/1999/xhtml" style="">// #c---  
  2. /*==========================================================================* 
  3.  * @Description: 
  4.  *      初始化unicode(key)与GBK(value)的映射表tab_UCS2_to_GBK 
  5.  * 
  6.  * @Returns: 
  7.  *      成功, 返回1; 
  8.  *      失败, 返回0. 
  9.  * 
  10.  *==========================================================================*/  
  11. static int enc_stc_unicode_to_GBK_init()  
  12. {  
  13.     assert(tab_UCS2_to_GBK == NULL);  
  14.   
  15.     int  i;  
  16.     void *ret;  
  17.   
  18.     tab_UCS2_to_GBK = Table_new(21791, enc_stc_unicode_to_GBK_cmp,  
  19.             enc_stc_unicode_to_GBK_hash);  
  20.     if ( tab_UCS2_to_GBK == TABLE_ERROR )  
  21.         return 0;  
  22.   
  23.     for ( i = 0; i < NUMOF_TAB_GBK_TO_UCS2; i++ )  
  24.     {  
  25.         if ( tab_GBK_to_UCS2[i][1] == 0x0001 )  
  26.             continue;  
  27.   
  28.         unsigned long k = (unsigned long)tab_GBK_to_UCS2[i][1];  
  29.         unsigned long v = (unsigned long)tab_GBK_to_UCS2[i][0];  
  30.         ret = Table_put(tab_UCS2_to_GBK, (void*)k, (void*)v);  
  31.         if ( ret != TABLE_OK )  
  32.             return 0;  
  33.     }  
  34.   
  35.     return 1;  
  36. }  
  37.   
  38. /***************************************************************************** 
  39.  * 将一个字符的Unicode(UCS-2和UCS-4)编码转换成GBK编码. 
  40.  * 
  41.  * 参数: 
  42.  *    ucs      字符的Unicode编码值 
  43.  *    gbk      指向输出的用于存储GBK编码值的缓冲区的指针 
  44.  * 
  45.  * 返回值: 
  46.  *    1. 成功则返回该字符的GBK编码所占用的字节数; 
  47.  *         对于ASCII字符返回1, 对于非ASCII中文字符返回2. 
  48.  *    2. 失败则返回0. 
  49.  * 
  50.  * 注意: 
  51.  *     1. GKB和Unicode都有字节序要求; 
  52.  *        字节序分为大端(Big Endian)和小端(Little Endian)两种; 
  53.  *        在Intel处理器中采用小端法表示, 在此采用小端法表示. (低地址存低位) 
  54.  ****************************************************************************/  
  55. int enc_unicode_to_GBK_one(unsigned long ucs, unsigned short *gbk)  
  56. {  
  57.     assert(gbk != NULL);  
  58.   
  59.     if ( ucs < 0x80 )  
  60.     {  
  61.         *gbk = ucs;  
  62.         return 1;  
  63.     }  
  64.   
  65.     if ( tab_UCS2_to_GBK == NULL )  
  66.         if ( enc_stc_unicode_to_GBK_init() == 0 )  
  67.             return 0;  
  68.   
  69.     void *pvalue;  
  70.   
  71.     pvalue = Table_get(tab_UCS2_to_GBK, (void*)ucs);  
  72.     if ( pvalue == TABLE_NO_KEY )  
  73.         return 0;  
  74.   
  75.     *gbk = (unsigned long)pvalue;  
  76.   
  77.     return 2;  
  78. }  
  79.   
  80. // #c---end  
  81.   
  82.   
  83. </span></span>  

0 0
原创粉丝点击