Java 中文字符串编码之GBK转UTF-8
写过两篇关于编码的文章了,以为自己比较了解编码了呢?!
结果今天又结结实实的上了一课。
以前转来转去解决的问题终归还是简单的情形。即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的更多相关文章
- JAVA中文字符串编码--GBK转UTF-8
转载自:https://www.cnblogs.com/yoyotl/p/5979200.html 一.乱码的原因 gbk的中文编码是一个汉字用[2]个字节表示,例如汉字“内部”的gbk编码16进制的 ...
- java设置字符串编码、转码
Unicode(统一码.万国码.单一码)是计算机科学领域里的一项业界标准,包括字符集.编码方案等.Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一 ...
- java中字符串编码转换
Java 正确的做字符串编码转换 字符串的内部表示? 字符串在java中统一用unicode表示( 即utf-16 LE) , 对于 String s = "你好哦!"; 如果源码 ...
- python中文字符串编码问题
接口测试的时候,发现接口返回内容是uncodie类型但是包含中文.在使用print进行打印时输出提示错误: UnicodeEncodeError: 'ascii' codec can't encode ...
- 一文解开java中字符串编码的小秘密
目录 简介 Unicode的发展史 Unicode详解 UTF-8 UTF-16 UTF-32 Null-terminated string 和变种UTF-8 简介 在本文中你将了解到Unicode和 ...
- java String字符串编码类型转换
/** * 前后端数据乱码问题 * 解决办法1: * 乱码原因:一编一解码型不一致导致. * [main description] * @param {[type]} String[] args [d ...
- java获取字符串编码和转换字符串编码
public class EncodingUtil { // 这里可以提供更多地编码格式,另外由于部分编码格式是一致的所以会返回 第一个匹配的编码格式 GBK 和 GB2312 public stat ...
- PHP中文字符串编码转换
2016年2月26日 16:47:13 星期五 情景: PHP从csv导入数据时乱码 $name = mb_convert_encoding($name, 'UTF-8', 'ASCII,GBK,GB ...
- java 判断字符串编码
String iso8859 = new String(sb.toString().getBytes("iso8859-1"));String gbk = new String(s ...
随机推荐
- 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 ...
- ThinkPHP3.2.3 自定义标签库的使用
ThinkPHP 3.2.3 手册中标签库驱动的地址是: http://www.kancloud.cn/manual/thinkphp/1859 标签库的地址是:http://www.kancloud ...
- Nginx + php-fpm 执行 PHP 脚本超时 报错 502 Bad Gateway + 504 Gateway Time-out 的解决办法
上周写好的发送邮件的计划任务只发送了一部分,检查计划任务日志,发现 502 Bad Gateway 的错误(已经在脚本中设置了 set_time_limit(0)). 后来在网上查找资料,可以通过以下 ...
- javascript大神修炼记(7)——OOP思想(多态)
读者朋友们大家好,今天我们就接着前面的内容讲,前面我们已经讲到了继承,今天我们就来讲OOP目前最后一个体现,那就是多态,因为javascript语言的灵活性,所以我们是没有办法使用接口的,所以这也给j ...
- 【axc】简单的线性动画绘制
在一个View上绘制一条直线 然后做出相应的动画效果 可以这样封装三个方法: /** * 划线工具 * * @param lineArray 线段的点数组 NSValue 类型 默认第一 ...
- 盒模型中--border
三要素:宽border-width,形状border-style,颜色border-color <style> div{ width:300px; height:300px; backgr ...
- des加密解密的两个方法
<?php //$input - stuff to decrypt //$key - the secret key to use function do_mencrypt($input, $ke ...
- IOS开始对App Store大扫除:你的APP更新了吗?
成都亿合科技小编从北京商报了解到,对于开发APP应用的要注意啦,IOS要开始对App Store大扫除:你的APP更新了吗? 日前苹果App Store的开发者们发送邮件,表示将实施一个持续评估应用行 ...
- WIN8系统安装软件时提示"扩展属性不一致"的解决方法
单位新添加了两台T440P笔记本电脑,需要安装五笔输入法,同事一直安装不上.开始以为是WIN8系统跟输入法不兼容的问题,怀疑是输入法下载有误.于是直接在输入法官网下载了输入法,问题依旧:扩展属性不一致 ...
- paper 105: 《Single Image Haze Removal Using Dark Channel Prior》一文中图像去雾算法的原理、实现、效果及其他
在图像去雾这个领域,几乎没有人不知道<Single Image Haze Removal Using Dark Channel Prior>这篇文章,该文是2009年CVPR最佳论文.作者 ...