写过两篇关于编码的文章了,以为自己比较了解编码了呢?!

结果今天又结结实实的上了一课。

以前转来转去解决的问题终归还是简单的情形。即iso-8859-1转utf-8,或者iso-8859-1转gbk,gb2312之类。这种无损转换,一行代码就搞定。

今天遇到了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+4+2+2=24。

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

三、不要重复发明轮子

这段代码测试可用还很好用,需要的可以参考。

 public static String getUTF8StringFromGBKString(String gbkStr) {
try {
return new String(getUTF8BytesFromGBKString(gbkStr), "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new InternalError();
}
} public static byte[] getUTF8BytesFromGBKString(String gbkStr) {
int n = gbkStr.length();
byte[] utfBytes = new byte[ * n];
int k = ;
for (int i = ; i < n; i++) {
int m = gbkStr.charAt(i);
if (m < && m >= ) {
utfBytes[k++] = (byte) m;
continue;
}
utfBytes[k++] = (byte) (0xe0 | (m >> ));
utfBytes[k++] = (byte) (0x80 | ((m >> ) & 0x3f));
utfBytes[k++] = (byte) (0x80 | (m & 0x3f));
}
if (k < utfBytes.length) {
byte[] tmp = new byte[k];
System.arraycopy(utfBytes, , tmp, , k);
return tmp;
}
return utfBytes;
}

PS:有点儿对不住原作者,找了很多代码,一一测试,结果网页都关闭了,如果有大神认领,我一定补充链接,而且深表感谢。

Java 中文字符串编码之GBK转UTF-8的更多相关文章

  1. JAVA中文字符串编码--GBK转UTF-8

    转载自:https://www.cnblogs.com/yoyotl/p/5979200.html 一.乱码的原因 gbk的中文编码是一个汉字用[2]个字节表示,例如汉字“内部”的gbk编码16进制的 ...

  2. java设置字符串编码、转码

    Unicode(统一码.万国码.单一码)是计算机科学领域里的一项业界标准,包括字符集.编码方案等.Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一 ...

  3. java中字符串编码转换

    Java 正确的做字符串编码转换 字符串的内部表示? 字符串在java中统一用unicode表示( 即utf-16 LE) , 对于 String s = "你好哦!"; 如果源码 ...

  4. python中文字符串编码问题

    接口测试的时候,发现接口返回内容是uncodie类型但是包含中文.在使用print进行打印时输出提示错误: UnicodeEncodeError: 'ascii' codec can't encode ...

  5. 一文解开java中字符串编码的小秘密

    目录 简介 Unicode的发展史 Unicode详解 UTF-8 UTF-16 UTF-32 Null-terminated string 和变种UTF-8 简介 在本文中你将了解到Unicode和 ...

  6. java String字符串编码类型转换

    /** * 前后端数据乱码问题 * 解决办法1: * 乱码原因:一编一解码型不一致导致. * [main description] * @param {[type]} String[] args [d ...

  7. java获取字符串编码和转换字符串编码

    public class EncodingUtil { // 这里可以提供更多地编码格式,另外由于部分编码格式是一致的所以会返回 第一个匹配的编码格式 GBK 和 GB2312 public stat ...

  8. PHP中文字符串编码转换

    2016年2月26日 16:47:13 星期五 情景: PHP从csv导入数据时乱码 $name = mb_convert_encoding($name, 'UTF-8', 'ASCII,GBK,GB ...

  9. java 判断字符串编码

    String iso8859 = new String(sb.toString().getBytes("iso8859-1"));String gbk = new String(s ...

随机推荐

  1. HDU 5416 CRB and Tree(前缀思想+DFS)

    CRB and Tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Tot ...

  2. Javascript备忘模式

    使用备忘模式,利用了函数的自定义属性,先看一个例子 var test = function (){} test.myAttr = "attr"; 这样,就给test加上了一个自定义 ...

  3. jqGrid通用编辑规则

    一个将数据显示在grid中主要的原因是为了快速容易的编辑它,jqGrid支持3种编辑方法 jqGrid单元格编辑配置,事件及方法::编辑表格中的单元格 jqGrid行编辑配置:同时编辑一行中的多个单元 ...

  4. LeetCode 3Sum Smaller

    原题链接在这里:https://leetcode.com/problems/3sum-smaller/ 题目: Given an array of n integers nums and a targ ...

  5. Did not find handler method for springMVC资源文件扫描不到---关于spring的那些坑

    今天将项目的spring版本升级到4.2.5版本后,登录首页发现资源文件全部访问不到,页面彻底挂掉: 查找原因,后来又查找spring的更新文档后,才确认下来原来是mvc-dispatcher-ser ...

  6. ArrayList 排序Sort()方法扩展

    1.sort() sort可以直接对默认继承 IComparable接口的类进行排序,如:int.string.... ArrayList arrayList = new ArrayList(); , ...

  7. html2canvaces用法,js截屏并且下载

    1.首先自己下载引入html2canvaces和jquery(我的demo路径是自己本地的) 2.点击截屏按钮后,跳出层的其他部分是取消保存,点击截取获得的图片区域,表示保存 <!DOCTYPE ...

  8. tcp_tw_recycle 的问题, 使用某一个wifi,APP老是连接不上网络

    ss -tan 反映出来的情况就是在服务器上抓包,发现有SYN包,但服务器就是不回ACK包,因为SYN包已经被丢弃了.为了验证这一结果,可以执行netstat -s | grep timestamp ...

  9. java 8 新特性

    最近在IDEA的️驱使下,看了点java8的东西,链接贴一下,,,,, 1.Java 8新特性概述2.Java 8中的 Stream API 详解[3.Java 8新特性终极指南] 简单的使用看完新特 ...

  10. Go 模板

    原文链接 很多语言都有很多方式将字符串从一只形式转换成另一种形式.Go 使用模板的方法通过提供一个对象作为参数来转换字符串.这个一般来讲是用来将对象插入到HTML中的,不过它同样可以用在其他的情况下. ...