引用
该篇文章引用自:http://www.blogjava.net/pengpenglin/archive/2010/02/22/313669.html
【GBK转UTF-8】
--------------------------------------------------------------------------------
在很多论坛、网上经常有网友问“ 为什么我使用 new String(tmp.getBytes("ISO-8859-1"), "UTF-8") 或者 new String(tmp.getBytes("ISO-8859-1"), "GBK")可以得到正确的中文,但是使用 new String(tmp.getBytes("GBK"), "UTF-8") 却不能将GBK转换成UTF-8呢?”
参考前面的【Java基础专题】编码与乱码(03)----String的toCharArray()方法测试 一文,我们就知道原因了。因为如果客户端使用GBK、UTF-8编码,编码后的字节经过ISO-8859-1传输,再用原来相同的编码方式进行解码,这个过程是“无损的转换”---- 因为原始和最终的编码方式相同。
但是如果客户端使用GBK编码,到了服务器端要转换成UTF-8,或者相反的过程。想一想,字节还是那些字节,但是编码的规则变了。原来GBK编码后的4个字节要用UTF-8的每个字符3个字节的规则编码,怎么能不乱码呢?
所以从现在开始,不要再犯这种错误了。new String(tmp.getBytes("GBK"), "UTF-8") 这个过程,JVM内部是不会帮你自动对字节进行扩展以适应UTF-8的编码的。正确的方法应该是根据UTF-8的编码规则进行字节的扩充,即手动从2个字节变成3个字节,然后再转换成十六进制的UTF-8编码。
在这个专题的第一篇文章【Java基础专题】编码与乱码(01)---编码基础 开头,我们就已经介绍了这个规则:
①得到每个字符的2进制GBK编码
②将该16进制的GBK编码转换成2进制的字符串(2个字节)
③分别在字符串的首位插入110,在第9位插入10,在第17位插入10三个字符串,得到3个字节
④将这3个字节分别转换成16进制编码,得到最终的UTF-8编码。
下面给出一个从网络上得到的Java转码方法,原文链接见:http://jspengxue.iteye.com/blog/40781。下面的代码做了小小的修改
package example.encoding;
/** *//**
* The Class CharacterEncodeConverter.
*/
public class CharacterEncodeConverter {
/** *//**
* The main method.
*
* @param args the arguments
*/
public static void main(String[] args) {
try {
CharacterEncodeConverter convert = new CharacterEncodeConverter();
byte[] fullByte = convert.gbk2utf8("中文");
String fullStr = new String(fullByte, "UTF-8");
System.out.println("string from GBK to UTF-8 byte: " + fullStr);
} catch (Exception e) {
e.printStackTrace();
}
}
/** *//**
* Gbk2utf8.
*
* @param chenese the chenese
*
* @return the byte[]
*/
public byte[] gbk2utf8(String chenese) {
// Step 1: 得到GBK编码下的字符数组,一个中文字符对应这里的一个c[i]
char c[] = chenese.toCharArray();
// Step 2: UTF-8使用3个字节存放一个中文字符,所以长度必须为字符的3倍
byte[] fullByte = new byte[3 * c.length];
// Step 3: 循环将字符的GBK编码转换成UTF-8编码
for (int i = 0; i < c.length; i++) {
// Step 3-1:将字符的ASCII编码转换成2进制值
int m = (int) c[i];
String word = Integer.toBinaryString(m);
System.out.println(word);
// Step 3-2:将2进制值补足16位(2个字节的长度)
StringBuffer sb = new StringBuffer();
int len = 16 - word.length();
for (int j = 0; j < len; j++) {
sb.append("0");
}
// Step 3-3:得到该字符最终的2进制GBK编码
// 形似:1000 0010 0111 1010
sb.append(word);
// Step 3-4:最关键的步骤,根据UTF-8的汉字编码规则,首字节
// 以1110开头,次字节以10开头,第3字节以10开头。在原始的2进制
// 字符串中插入标志位。最终的长度从16--->16+3+2+2=24。
sb.insert(0, "1110");
sb.insert(8, "10");
sb.insert(16, "10");
System.out.println(sb.toString());
// Step 3-5:将新的字符串进行分段截取,截为3个字节
String s1 = sb.substring(0, 8);
String s2 = sb.substring(8, 16);
String s3 = sb.substring(16);
// Step 3-6:最后的步骤,把代表3个字节的字符串按2进制的方式
// 进行转换,变成2进制的整数,再转换成16进制值
byte b0 = Integer.valueOf(s1, 2).byteValue();
byte b1 = Integer.valueOf(s2, 2).byteValue();
byte b2 = Integer.valueOf(s3, 2).byteValue();
// Step 3-7:把转换后的3个字节按顺序存放到字节数组的对应位置
byte[] bf = new byte[3];
bf[0] = b0;
bf[1] = b1;
bf[2] = b2;
fullByte[i * 3] = bf[0];
fullByte[i * 3 + 1] = bf[1];
fullByte[i * 3 + 2] = bf[2];
// Step 3-8:返回继续解析下一个中文字符
}
return fullByte;
}
}
最终的测试结果是正确的:string from GBK to UTF-8 byte: 中文。
但是这个方法并不是完美的!要知道这个规则只对中文起作用,如果传入的字符串中包含有单字节字符,如a+3中文,那么解析的结果就变成:string from GBK to UTF-8 byte: ?????????中文了。为什么呢?道理很简单,这个方法对原本在UTF-8中应该用单字节表示的数字、英文字符、符号都变成3个字节了,所以这里有9个?,代表被转换后的a、+、3字符。
所以要让这个方法更加完美,最好的方法就是加入对字符Unicode区间的判断
UCS-2编码(16进制) UTF-8 字节流(二进制)
0000 - 007F 0xxxxxxx
0080 - 07FF 110xxxxx 10xxxxxx
0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx
汉字的Unicode编码范围为\u4E00-\u9FA5 \uF900-\uFA2D,如果不在这个范围内就不是汉字了。
【UTF-8转GBK】
道理和上面的相同,只是一个逆转的过程,不多说了
但是最终的建议还是:能够统一编码就统一编码吧!要知道编码的转换是相当的耗时的工作
- 大小: 39.4 KB
分享到:
相关推荐
GBK、UTF-8批量文件3秒快速转码工具(支持GBK,UTF-8免费转换),UTF-8/GBK编码在线转换工具,压缩包可以有多目录与文件,如目录中有图片不会转码,但是会随转码好的文件一起打包下载。 使用帮助 . 上传压缩包(仅支持zip...
在C语言中,由于没有内置的GBK或UTF-8转换函数,我们需要自定义算法来实现编码转换。主要的过程可以分为两个步骤:首先从GBK转换到Unicode,然后从Unicode转换到UTF-8。 1. GBK转Unicode: - GBK编码中,每个字符...
本文将详细介绍如何在Microsoft Foundation Classes (MFC)环境下实现GBK与UTF-8之间的编码转换。该技术适用于那些需要处理不同字符集数据的应用程序开发场景,特别是在早期Windows系统中广泛使用的MFC框架下进行编码...
在这个例子中,`Encoding.GetEncoding("GBK")`获取了GBK编码器,`GetBytes()`方法将GBK编码的字符串转换为字节数组,然后`Encoding.UTF8.GetString()`将这个字节数组还原为UTF-8编码的字符串。 对于文件的编码转换...
本篇文章将详细探讨UTF-8与GBK编码,以及如何在LabVIEW环境下进行这两种编码之间的转换。 首先,UTF-8(Unicode Transformation Format - 8 bit)是一种变长的Unicode编码,它使用1到4个字节来表示一个字符。UTF-8...
在实际应用中,GBK和UTF-8之间的转换问题常常出现,尤其是在处理不同来源的数据时。例如,GBK编码的文件可能无法在支持UTF-8的系统中正确显示,反之亦然。描述中提到的“用vs2017写的”小程序就是为了解决这个问题,...
# 从UTF-8转换为GBK with codecs.open('UTF8_file.txt', 'r', 'utf-8') as utf8_file: content = utf8_file.read() with codecs.open('GBK_file.txt', 'w', 'gbk') as gbk_file: gbk_file.write(content) ``` 在...
在这个主题中,我们将深入探讨如何在C语言中进行UNICODE、GBK和UTF-8之间的转换。 UNICODE,也称为Unicode Transformation Format(UTF),是一种标准的字符编码,旨在表示世界上所有语言的每一个字符。它使用数字...
这篇博客文章“eclipse中class乱码GBK-UTF-8转换工具”正是为了解决这个问题。 GBK是GB2312的扩展,包含了更多的汉字和其他字符,主要在中国大陆使用。UTF-8则是一种广泛使用的Unicode编码,支持世界上几乎所有的...
- 在C语言中,我们可以编写函数来实现GBK和UTF-8之间的转换。文件`utf8gbk.h`和`utf8gbk.c`可能包含了这样的转换函数。 - 通常,从GBK转UTF-8需要将每个GBK编码的双字节序列转换为对应的Unicode码点,然后根据UTF-...
这些标签强调了工具的核心功能,即在GBK与UTF-8编码之间进行转换,这对于处理中文字符在不同系统或平台间兼容性问题非常重要。 在压缩包中的“GBK-UTF8.exe”文件名表明这可能是一个可执行文件,用户在Windows环境...
在C语言中,没有内置的GBK或UTF-8转换函数,因此需要手动编写转换算法。通常,这种转换涉及查找和使用字符映射表。GBK编码的每个字符都有一个对应的Unicode码点,而Unicode码点又可以转换为UTF-8编码。转换过程大致...
文件包含:gbk2utf-8.bat、utf-82gbk.bat、iconv.exe及使用说明.txt四个文件 使用说明:1把要转换的所有.h和.c文件拷入该目录下,双击相应的bat文件即可。 2转换结果会保存在utf-8Res或gbkRes目录下。 3如果转换除...
老项目采用GBK编码格式,而新项目采用的UTF-8编码格式,如果直接把Java源代码复制到Eclipse中所有的中文信息会出现乱码。所以写了个小的方法类,将java文件的编码格式从GBK转UTF-8
总的来说,"Eclipse项目的GBK编码转为UTF-8插件"是解决GBK到UTF-8编码转换问题的有效工具,它简化了开发者的工作流程,提高了代码管理的效率。对于那些经常需要处理不同编码格式项目的人来说,这样的工具无疑是非常...
标题中的“GBK转UTF-8批量转换”是指在计算机编程和文本处理领域中常见的字符编码转换过程。GBK和UTF-8是两种不同的字符编码标准,它们用于表示不同语言的字符集,尤其是中文字符。 GBK(Great Chinese Encoding)...
本文将详细介绍Unicode、ISO-8859-1、GBK和UTF-8这四种常见的字符编码,并探讨它们之间的转换方法。 #### 二、基础知识 ##### 1. Unicode Unicode是一种国际字符编码标准,旨在支持世界上几乎所有语言的文字。它为...
GBK编码和UTF-8编码是两种广泛使用的字符编码标准,它们各有特点,但不兼容,因此在不同环境下进行数据交换时,需要进行相应的转换。 GBK编码是中国大陆广泛采用的一种汉字编码标准,它是GB2312的扩展,包含了更多...