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

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

以前转来转去解决的问题终归还是简单的情形。即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. Transform a BST to greater sum tree

    Given a BST, transform it into greater sum tree where each node contains sum of all nodes greater th ...

  2. ThinkPHP3.2.3 自定义标签库的使用

    ThinkPHP 3.2.3 手册中标签库驱动的地址是: http://www.kancloud.cn/manual/thinkphp/1859 标签库的地址是:http://www.kancloud ...

  3. Nginx + php-fpm 执行 PHP 脚本超时 报错 502 Bad Gateway + 504 Gateway Time-out 的解决办法

    上周写好的发送邮件的计划任务只发送了一部分,检查计划任务日志,发现 502 Bad Gateway 的错误(已经在脚本中设置了 set_time_limit(0)). 后来在网上查找资料,可以通过以下 ...

  4. javascript大神修炼记(7)——OOP思想(多态)

    读者朋友们大家好,今天我们就接着前面的内容讲,前面我们已经讲到了继承,今天我们就来讲OOP目前最后一个体现,那就是多态,因为javascript语言的灵活性,所以我们是没有办法使用接口的,所以这也给j ...

  5. 【axc】简单的线性动画绘制

    在一个View上绘制一条直线  然后做出相应的动画效果  可以这样封装三个方法: /** *  划线工具 * *  @param lineArray   线段的点数组 NSValue 类型  默认第一 ...

  6. 盒模型中--border

    三要素:宽border-width,形状border-style,颜色border-color <style> div{ width:300px; height:300px; backgr ...

  7. des加密解密的两个方法

    <?php //$input - stuff to decrypt //$key - the secret key to use function do_mencrypt($input, $ke ...

  8. IOS开始对App Store大扫除:你的APP更新了吗?

    成都亿合科技小编从北京商报了解到,对于开发APP应用的要注意啦,IOS要开始对App Store大扫除:你的APP更新了吗? 日前苹果App Store的开发者们发送邮件,表示将实施一个持续评估应用行 ...

  9. WIN8系统安装软件时提示"扩展属性不一致"的解决方法

    单位新添加了两台T440P笔记本电脑,需要安装五笔输入法,同事一直安装不上.开始以为是WIN8系统跟输入法不兼容的问题,怀疑是输入法下载有误.于是直接在输入法官网下载了输入法,问题依旧:扩展属性不一致 ...

  10. paper 105: 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果及其他

    在图像去雾这个领域,几乎没有人不知道<Single Image Haze Removal Using Dark Channel Prior>这篇文章,该文是2009年CVPR最佳论文.作者 ...