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 ...
随机推荐
- C# Color
一.创建一个Color对象: Color c=Color.FromKnownColor(KnownColor.colorname); 二.四种同样颜色的不同方式: Color c1=Color.Fro ...
- 安装Arch Linux(桌面环境)
安装xorg-server # pacman -S xorg-server xorg-server-utils xorg-xinit 安装显卡驱动 如果不知道是什么显卡,就使用以下命令查看 # lsp ...
- Apache Spark技术实战之4 -- 利用Spark将json文件导入Cassandra
欢迎转载,转载请注明出处. 概要 本文简要介绍如何使用spark-cassandra-connector将json文件导入到cassandra数据库,这是一个使用spark的综合性示例. 前提条件 假 ...
- PHP 标准库 SPL 之数据结构栈(SplStack)简单实践
PHP 5.3.0 版本及以上的堆栈描述可以使用标准库 SPL 中的 SplStack class,SplStack 类继承双链表 ( SplDoublyLinkedList ) 实现栈. 代码: & ...
- lua 可变参数
问题:对可变参数传递的时候,采用如下方案: local cellData = {MsgText = msgText,Param = ...,CallBackFunc = callBackFunc,Ca ...
- XHTML表单
1.HTML表单标记提供一套元素和属性,用来创建表单,收集网页参观者信息. 2.创建表单结构标记为<form>和</form>. 3.在<form>标记中,我们必须 ...
- ArcGIS Server,4000端口被占用
server使用的端口:http://resources.arcgis.com/zh-cn/help/main/10.2/index.html#//015400000537000000 cmd 输入命 ...
- JDBC操作
String sql = "SELECT * from lib where name = ?";List<Lib> list = getJdbcTemplate().q ...
- 服务设计模式一:Web服务概述
目录 1. Web服务是什么 2.为什么要使用Web服务 3.Web服务考虑的因素和替代方案 4.SOA是什么 Web服务是什么? 所谓服务,通俗的理解就是别人帮你做一些事情,比如说,腰酸背痛了,找个 ...
- 如何关闭windows电脑的开机自启程序
很多时候我们打开电脑会发现,莫名其妙的出现一些已经在运行的程序了,这都是一些开机自启的软件之类的.可能你的电脑配置本来就不怎么高,开机还这样,那估计会很卡顿,那有什么方法可以关闭这些开机自动启动的程序 ...