可以成功转utf8并转回吗?如果可以的话,
String old = "中文的";
String u8 = new String(old.getBytes("gbk"),"utf-8");
String gb = new String(u8.getBytes("utf-8"),"gbk");
System.out.println(u8);
System.out.println(gb);//会乱码
思路错在哪里
String old = "中文的";
String u8 = new String(old.getBytes("gbk"),"utf-8");
String gb = new String(u8.getBytes("utf-8"),"gbk");
System.out.println(u8);
System.out.println(gb);//会乱码
思路错在哪里
因为对UTF-8合法的字节数组可能对GB不合法,反之也一样。
即,UTF-8和GB不是二进制相容的。GB和ISO-8859-1可以这样互转,它们是二进制相容的。
import java.net.URLDecoder;
import java.net.URLEncoder;public class Test {
public static void main(String[] args) {
String str = "测试字符转换 hello word"; //默认环境,已是UTF-8编码
try {
String strGBK = URLEncoder.encode(str, "GBK");
System.out.println(strGBK);
String strUTF8 = URLDecoder.decode(str, "UTF-8");
System.out.println(strUTF8);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws UnsupportedEncodingException {
String old = "测试字符转换 ";//默认环境,已是UTF-8编码
String gb = new String(old.getBytes("UTF-8"), "GBK");
System.out.println(""+gb);
String u8 = new String(gb.getBytes("GBK"), "UTF-8");
System.out.println(u8);// 没有乱码
}
}
The results:
娴嬭瘯瀛楃杞崲
测试字符转换
谢高手.
utf8应该包含"中文的"这样的中文吧,虽然编码位置不同于gb。
"UTF-8和GB不是二进制相容",我理解String(old.getBytes("gbk"),"utf-8")是将gbk的二进制转换成utf8相应的二进制,不知理解错在哪
public static void main(String[] args) throws Exception{
String old = "中文的";
String s1 = new String(old.getBytes("gbk"),"iso-8859-1");
String s2 = new String(s1.getBytes("iso-8859-1"),"gbk");
System.out.println(s1);
System.out.println(s2);//中文的
String str = new String(old.getBytes("gbk"),"gbk");
System.out.println(str);//中文的
}
String old = "中文的 abcd";
byte [] utf8Decode = old.getBytes("utf-8");
System.out.println("utf8:");
for (byte b: utf8Decode) {
System.out.print(Integer.toHexString(b & 0xFF));
System.out.print(" ");
}
System.out.println();
byte [] gbkDecode = old.getBytes("gbk");
System.out.println("gbk:");
for (byte b: gbkDecode) {
System.out.print(Integer.toHexString(b & 0xFF));
System.out.print(" ");
}
System.out.println();
System.out.println(new String(utf8Decode,"utf-8"));
System.out.println(new String(gbkDecode,"gbk"));output:
utf8:
e4 b8 ad e6 96 87 e7 9a 84 20 61 62 63 64
gbk:
d6 d0 ce c4 b5 c4 20 61 62 63 64
中文的 abcd
中文的 abcd在这里可以看出utf-8和gbk编码的汉字编码
http://topic.csdn.net/u/20080623/16/e0f44f00-eaf9-4d38-b325-a3cc443f2ec9.html
这里就是国标区位码表:http://www.xaipe.edu.cn/xwfb/newsfile/20061218120842.doc
Unicode码表请查看官网。但是处理不同的标准是痛苦的,如汉语,台湾有一个Big5编码标准,很多编码和国标是相同的,为了解决中文问题,不能从扩展ASCII的角度入手,也不能仅靠中国一家来解决。而必须有一个全新的编码系统,这个系统要可以将中文、英文、法文、德文……等等所有的文字统一起来考虑,为每个文字都分配一个单独的编码,这样才不会有上面那种现象出现。于是,Unicode诞生了。以上就是我们说的字符集,下面简单说下字符集编码:Java中Unicode用两个字节表示(UCS-2),但只规定了怎么用多个字节表示各种文字,怎样传输这些编码,这就是由UTF(UCS Transformation Format)规范规定的,常见的UTF规范包括UTF-8、UTF-16等,这就是字符集编码;这里只说UTF-8:
UTF-8用1到6个字节编码UNICODE字符。如果Unicode字符由2个字节表示,则编码成UTF-8很可能需要3个字节,UFT-8转换表表示如下:
UNICODE UTF-8
0000 - 007F 0xxxxxxx
0080 - 07FF 110xxxxx 10xxxxxx
0800 - FFFF 1110xxxx 10xxxxxx 10xxxxxx如'中'的Unicode是 4e2d,显然落在了0800 - FFFF 区,就用三个字节表示:11100100 10111000 10101101; 就是把4e2d转换成2进制0100 1110 0010 1101,依次填入XXX符号就行了。
国标码,全称是GB2312-80, 要理解国标码,楼主得先理解 区位码、国标码与机内码的关系;简单说下:
(1)区位码先转换成十六进制数表示
(2)区位码(十六进制)+2020H=国标码(十六进制);(两位两位相加)
(3)国标码(十六进制)+8080H=机内码(十六进制); (两位两位相加)国标码是不可能在计算机内部直接采用的,与ASCII码发生冲突,如'保' 字,国标码为31H和23H,而西文字符“1”和“#”的SCII也为31H和23H,现假如内存中有两个字节为31H和23H,;这到底是一个汉字,还是两个西文字符“1”;和“#”? 于是就出现了二义性.
所以是用机内码表示的,其实就是GBK编码,该编码标准兼容GB2312;还说下区位码的来由:
国标码汉字及符号组成一个94行94列的二维代码表中。在此方阵中,每一行称为一个"区",每一列称为一个"位"。这个方阵实际上组成一个有94个区(编号由01到94),每个区有94个位(编号由01到94)的汉字字符集。每两个字节分别用两位十进制编码,前字节的编码称为区码,后字节的编码称为位码,此即区位码,其中,高两位为区号,低两位为位号。这样区位码可以唯一地确定某一汉字或字符;反之,任何一个汉字或符号都对应一个唯一的区位码,没有重码。由上面的关系可以知道: 机内码(十六进制) = 区位码(十六进制) + A0A0H;如'中'的区位码是5448,表示的是'中'在54区,48位,GBK怎样编码呢?如下:
5448的十六进制是3630;
3630 + A0A0 = D6D0;
D6D0就是GBK编码了;这里有个编码表查询 http://blog.csdn.net/boliu218/archive/2011/01/06/6119710.aspx;说了这么多,以下不说楼主也基本明白了。
String old = "中文的";//这里在JVM中是Unicode
String u8 = new String(old.getBytes("gbk"),"utf-8");//这里用GBK编码,注意不再是字符串或字符了,是字节,看下GBK编码11010110 11010000 d6d0 11001110 11000100 cec4 10110101 11000100 b5c4, 你解码时用UTF-8,11010110前的110XXXXX告诉解码器是要连续两个字节来解码,问题来了,UTF-8的规范是后一个字节形式是10XXXXXX,可这里是11010000,显然处理不了,这里就要看JVM的实现,我用的是IBM的JDK,他的处理是解码不了就舍弃这两个字节,后面同样处理了。所以返回一个空字符串。
String gb = new String(u8.getBytes("utf-8"),"gbk");//上面返回了个空字符串,这里就没什么编码解码了,gb就是空的。
System.out.println(u8);//无输出
System.out.println(gb);//无数出如果new String(old.getBytes("gbk"),"utf-8");这一步解码的处理不会发字节丢失或字节替换,后面的new String(u8.getBytes("utf-8"),"gbk");是能成功转回去的,问题是前面的解码中UTF-8能表示出GBK的编码,哪怕是我们说的乱码。
magong
(行者67685C1196C4) bao110908
()火龙果() 结帖.