转载自: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

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

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

    写过两篇关于编码的文章了,以为自己比较了解编码了呢?! 结果今天又结结实实的上了一课. 以前转来转去解决的问题终归还是简单的情形.即iso-8859-1转utf-8,或者iso-8859-1转gbk, ...

  2. java中字符串编码转换

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

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

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

  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. C 语言实例 - 判断奇数/偶数

    C 语言实例 - 判断奇数/偶数 C 语言实例 C 语言实例 以下实例判断用户输入的整数是奇数还是偶数. 实例 #include <stdio.h> int main() { int nu ...

  2. com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException: INSTALL_FAILED_ABORTED: User rejected permissions

    原因是连接了两个设备,所以无法启动,关掉一个即可

  3. 线程组之间的JMeter传递变量

    在这个JMeter教程中,我们将了解如何在线程组之间共享和传递变量. 在开发高级JMeter脚本时,很可能您将拥有多个线程组.每个线程组将执行不同的请求. 一个很好的例子就是我们需要使用Bearer ...

  4. python所有的魔术方法

    据说,Python 的对象天生拥有一些神奇的方法,它们总被双下划线所包围,他们是面向对象的 Python 的一切. 他们是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个, ...

  5. Django配置文件解释

    """Django settings for first project. Generated by 'django-admin startproject' using ...

  6. 牛客假日团队赛2 C.修围栏

    链接: https://ac.nowcoder.com/acm/contest/924/C 题意: 农民 John 希望修复围绕农场的一小段围栏.他测量了一下,发现需要N (1 <= N < ...

  7. jQuery背景插件backstretch使用指南

    http://www.bkjia.com/Javascript/987917.html

  8. WebApi迁移ASP.NET Core2.0

    WebApi迁移ASP.NET Core2.0 一步一步带你做WebApi迁移ASP.NET Core2.0   随着ASP.NET Core 2.0发布之后,原先运行在Windows IIS中的AS ...

  9. 为什么用B+树做索引&MySQL存储引擎简介

    索引的数据结构 为什么不是二叉树,红黑树什么的呢? 首先,一般来说,索引本身也很大,不可能全部存在内存中,因此索引往往以索引文件的方式存在磁盘上.然后一般一个结点一个磁盘块,也就是读一个结点要进行一次 ...

  10. c++笔记3

    一基本语法: 1.1 字符串:支持标准C的 const char* pch=0/"";//不指向任何对象和指向空字符串.C++提供的string类可提供字符串的所有操作,最好是融合 ...