zoukankan      html  css  js  c++  java
  • JAVA中文字符串编码--GBK转UTF-8

    转载自:https://www.cnblogs.com/yoyotl/p/5979200.html

    一、乱码的原因

    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+4+2+2=24。

    3.转换完成,实际情况需要考虑更多因素,例如字符串是汉字和数字的混合体,需要识别处理数字。

    public void entityTest(){
    try {
    byte[] str = "支持™".getBytes("gbk");
    String gbkStr = new String(str, "gbk");
    System.out.println(new String(getUTF8BytesFromGBKString(gbkStr),"UTF-8"));
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }
    }


    public static byte[] getUTF8BytesFromGBKString(String gbkStr) {
    int n = gbkStr.length();
    byte[] utfBytes = new byte[3 * n];
    int k = 0;
    for (int i = 0; i < n; i++) {
    int m = gbkStr.charAt(i);
    if (m < 128 && m >= 0) {
    utfBytes[k++] = (byte) m;
    continue;
    }
    utfBytes[k++] = (byte) (0xe0 | (m >> 12));
    utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f));
    utfBytes[k++] = (byte) (0x80 | (m & 0x3f));
    }
    if (k < utfBytes.length) {
    byte[] tmp = new byte[k];
    System.arraycopy(utfBytes, 0, tmp, 0, k);
    return tmp;
    }
    return utfBytes;
    }

     但在这里还是有个问题是"支持™"字符串中"™"的字符由于在GBK中不存在,那么在byte[] str = "支持™".getBytes("gbk");的时候"™"字符就已经乱码了,最后导致转码也乱码。GBK还有很多不支持的特殊字符。

    GBK字符编码表:https://www.qqxiuzi.cn/zh/hanzi-gbk-bianma.php

  • 相关阅读:
    nginx学习,下载、安装。使用:正向代理、反向代理、负载均衡
    idea一键导入所有包
    开源小工具-随机生成图片验证码
    记一次Nginx报错403(Permission denied)
    记一次swf视频转mp4经历
    enumerate函数
    filter函数过滤序列
    RetinaNet pytorch implement from scratch 03--Focal Loss
    [读论文]Weighted Boxes Fusion 代替NMS的result ensemble
    Pytorch使用autograd.function自定义op
  • 原文地址:https://www.cnblogs.com/EmilZs/p/10985792.html
Copyright © 2011-2022 走看看