字符集的编码的总结

一、常用的字符集编码

  ASCII(American Standard Code for Information Interchange,美国信息互换标准代码),是基于常用的英文字符的一套电脑编码系统。我们知道英文中经常使用的字符、数字符号被计算机处理时都是以二进制码的形式出现的。这种二进制码的集合就是所谓的ASCII码。每一个ASCII码与一个8位(bit)二进制数对应。其最高位是0,相应的十进制数是0-127。如,数字“0”的编码用十进制数表示就是48。另有128个扩展的ASCII码,最高位都是1,由一些制表符和其它符号组成。ASCII是现今最通用的单字节编码系统。

常见ASCII码的大小规则:0~9<A~Z<a~z    “0”为 48;“A”为65;“a”为97;(同个大写字母比小写字母小32) 空格键: 32

GB2312:GB2312码是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集-基本集》。主要用于给每一个中文字符指定相应的数字,也就是进行编码。一个中文字符用两个字节的数字来表示,为了和ASCII码有所区别,将中文字符每一个字节的最高位置都用1来表示。

GBK:为了对更多的字符进行编码,国家又发布了新的编码系统GBK(GBK的K是“扩展”的汉语拼音第一个字母)。在新的编码系统里,除了完全兼容GB2312 外,还对繁体中文、一些不常用的汉字和许多符号进行了编码

ISO-8859-1:是西方国家所使用的字符编码集,是一种单字节的字符集 ,而英文实际上只用了其中数字小于128的部分。

Unicode:这是一种通用的字符集,对所有语言的文字进行了统一编码,对每一个字符都用2个字节来表示,对于英文字符采取前面加“0”字节的策略实现等长兼容。如 “a” 的ASCII码为0x61,UNICODE就为0x00,0x61。

Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

UTF-8:Eight-bit UCS Transformation Format,(UCS,Universal Character Set,通用字符集,UCS 是所有其他字符集标准的一个超集)。一个7位的ASCII码值,对应的UTF码是一个字节。如果字符是0x0000,或在0x0080与0x007f之间,对应的UTF码是两个字节,如果字符在0x0800与0xffff之间,对应的UTF码是三个字节。

UTF-8就是在互联网上使用最广的一种Unicode的实现方式。其他实现方式还包括UTF-16(字符用两个字节或四个字节表示)和UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。
UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。


二、编码、解码

解码:在InputStreamReader JDK有这样描述:It reads bytes and decodes them into characters using a specified charset.

用指定的字符集将字节数组解码成字符串
编码:相反OutputStreamWriter 描述:Characters written to it are encoded into bytes using a specified charset.(

用指定的字符集将字符串编码成字节数组

查看JVM支持的编码种类:

Map m = Charset.availableCharsets();
  Set names = m.keySet();
  Iterator it = names.iterator();
   while (it.hasNext())
   {
   System.out.println(it.next());
  }
查看目前JVM所使用的编码:

 Properties pps = System.getProperties();
    pps.list(System.out);
 我们的OS一般是GBK编码的(凡是从磁盘上读取文件可以看成是用OS的字符集编码方式来对操作对象进行解码处理--从标准输入设备读取数据的时候是依赖OS的字符集)。而我们将从磁盘上文件经过处理得到我们想要的字符串等其它对象的时候,这一过程是用JVM的默认的字符集编码方式来处理的!由于不同的字符集编码方式有着不同的原理(前面所述),这样当编码与解码不一致的时候,自然而然就出现了乱码。

这时我们可以用string的一个构造方法:
  String(byt[] bytes, String charsetName) 
  Constructs a 
new String by decoding the specified array of bytes using the specified charset.(用指定的字符集对字节数组进行解码)。
  其中用到了string 的getBytes方法:
  getBytes(String charsetName) 
  Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array.(用指定的字符集进行编码,将结果存放到一字节数组里面)重新构造一个string:

  String strGBK  =  new   String(str.getBytes(  " JVM编码 "  ),  "  GBK  "  );
从而使OS和JVM的编码一致,解决乱码。

例子中是GBK(OS)来编码的,然后采用iso-8859-1(JVM)来解码得到一个新string(此string是乱码),然后将此string用iso-8859-1重新编码,并且用指定的GBK来解码。得到一个新string(也就是strGBK),这个string就不再是乱码了。

  但如果我们一开始就采用GBK解码得到的字符串,然后用ISO-8859-1编码,能否再解码回去得到我们的中文字符呢?显示不可以啦,因为用ISO-8859-1的编码的时候采用是一种单字节的字符集来对其编码,这样就丢失了一个字节(对中文来说)!所以这样是得不到中文字符的!


参考:

http://www.blogjava.net/Jkallen/archive/2006/06/29/55666.html


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值