[转]字符在utf-8,gbk,gb2312,iso8859-1下的编码实验

出处http://sunfish.blog.51cto.com/417500/142577

一直以来对编码并不是太理解,所以用java做了个实验,感觉清楚了点:
下面这个代码的功能是,获取某个字符或汉字在utf-8,gbk,gb2312,iso8859-1等下的十六进制,八进制,十进制,二进制的表示 (当然,只有二进制才是其在计算机中的 真真表示.)
import java.io.UnsupportedEncodingException;

public class CharEncode {
   /**
    * @param str
    *                        字符
    * @param charsetName
    *                        编码
    * @param debug
    *                        是否调试
    * @throws UnsupportedEncodingException
    */

   public static void displayEncode(String str, String charsetName,
       boolean debug) throws UnsupportedEncodingException {
    System.out.println( "----------------------------------");
     byte[] bytes = str.getBytes(charsetName);
     int bytes_length = bytes.length;

    System.out.println( "字符:" + str + "/t编码:" + charsetName + "/t共占用"
        + bytes_length + "bytes(字节)," + bytes_length * 8
        + "bit(位)/t每个字节的情况如下:");
     for ( int i = 0; i < bytes_length; i++) {

      System.out.print( "bytes[" + i + "]的十进制为:" + bytes[i]); // 获取byte字节

      Integer int_byte = ( int) bytes[i]; // 强制转化为int,应为bytes只占8bit,而int占32bit所以个人认为万无一失.

      String binaryString = Integer.toBinaryString(int_byte); // 获取整数的2进制的String表示方式
      String hexString = Integer.toHexString(int_byte); // 获取整数的16进制的String表示方式
      String octalString = Integer.toOctalString(int_byte); // 获取整数的16进制的String表示方式
       if (debug) {
        System.out.print( "/t对应的十进制为:" + int_byte);
        System.out.print( "/t对应整数的二进制为:" + binaryString);
        System.out.print( "/t对应整数的八进制为:" + octalString);
        System.out.print( "/t对应整数的十六进制为:" + hexString);
      }

       /** **八进制格式显示* */
       int octalString_length = octalString.length();
      System.out.print( "/t八进制为:"
          + octalString.substring(octalString_length - 2,
              octalString_length));
       /** **十六进制格式显示* */
       int hexString_length = hexString.length();
      System.out.print( "/t十六进制为:"
          + hexString.substring(hexString_length - 2,
              hexString_length));

       /** **为了方便阅读,将二进制以每4位一组的格式显示* */

       // 不足8位的,在前段加"0"补齐
       while (binaryString.length() < 8) {
        binaryString = "0" + binaryString;
      }
       int binaryString_length = binaryString.length();

      String first = binaryString.substring(binaryString_length - 8,
          binaryString_length - 4); // 取前4位
      String second = binaryString.substring(binaryString_length - 4,
          binaryString_length); // 取后4位

      System.out.println( "/t二进制为:" + first + " " + second);

    }
    System.out.println();
  }

   public static void main(String[] args) throws UnsupportedEncodingException {

     // 通过UltraEdit知道: 汉字"我"在gbk编码下的十六进制是"ced2";

     boolean debug = false;
    String str = "";
    String utf_8 = "utf-8";
    String gbk = "gbk";
    String gb2312 = "gb2312";
    String iso8859_1 = "iso8859-1";

    str = "我";
    System.out.println( "*****************" + str + "*******************/n");
    displayEncode(str, utf_8, debug);
    displayEncode(str, gbk, debug);
    displayEncode(str, gb2312, debug);
    displayEncode(str, iso8859_1, debug);

    str = "A";
    System.out.println( "*****************" + str + "*******************/n");
    displayEncode(str, utf_8, debug);
    displayEncode(str, gbk, debug);
    displayEncode(str, gb2312, debug);
    displayEncode(str, iso8859_1, debug);

    str = "1";
    System.out.println( "*****************" + str + "*******************/n");
    displayEncode(str, utf_8, debug);

  }
}

实验结果
如下:
*****************我*******************

----------------------------------
字符:我    编码:utf-8    共占用3bytes(字节),24bit(位)    每个字节的情况如下:
bytes[0]的十进制为:-26      八进制为:46    十六进制为:e6    二进制为:1110 0110
bytes[1]的十进制为:-120    八进制为:10    十六进制为:88    二进制为:1000 1000
bytes[2]的十进制为:-111    八进制为:21    十六进制为:91    二进制为:1001 0001

----------------------------------
字符:我    编码:gbk    共占用2bytes(字节),16bit(位)    每个字节的情况如下:
bytes[0]的十进制为:-50    八进制为:16    十六进制为:ce    二进制为:1100 1110
bytes[1]的十进制为:-46    八进制为:22    十六进制为:d2    二进制为:1101 0010

----------------------------------
字符:我    编码:gb2312    共占用2bytes(字节),16bit(位)    每个字节的情况如下:
bytes[0]的十进制为:-50    八进制为:16    十六进制为:ce    二进制为:1100 1110
bytes[1]的十进制为:-46    八进制为:22    十六进制为:d2    二进制为:1101 0010

----------------------------------
字符:我    编码:iso8859-1    共占用1bytes(字节),8bit(位)    每个字节的情况如下:
bytes[0]的十进制为:63    八进制为:77    十六进制为:3f    二进制为:0011 1111  (查ASSCII码表可得"?",常见的乱码,呵呵,但为什么先取得是这个二进制呢??????)

*****************A*******************

----------------------------------
字符:A    编码:utf-8    共占用1bytes(字节),8bit(位)    每个字节的情况如下:
bytes[0]的十进制为:65    八进制为:01    十六进制为:41    二进制为:0100 0001

----------------------------------
字符:A    编码:gbk    共占用1bytes(字节),8bit(位)    每个字节的情况如下:
bytes[0]的十进制为:65    八进制为:01    十六进制为:41    二进制为:0100 0001

----------------------------------
字符:A    编码:gb2312    共占用1bytes(字节),8bit(位)    每个字节的情况如下:
bytes[0]的十进制为:65    八进制为:01    十六进制为:41    二进制为:0100 0001

----------------------------------
字符:A    编码:iso8859-1    共占用1bytes(字节),8bit(位)    每个字节的情况如下:
bytes[0]的十进制为:65    八进制为:01    十六进制为:41    二进制为:0100 0001

*****************1*******************

----------------------------------
字符:1    编码:utf-8    共占用1bytes(字节),8bit(位)    每个字节的情况如下:
bytes[0]的十进制为:49    八进制为:61    十六进制为:31    二进制为:0011 0001


从中可以看出汉字在utf-8编码下,占用3个字节,GBK,gb2312占用2个字节,用iso8859-1只能取出一个字节(造成乱码的原因之一 )
另外 getBytes(charsetName);方法很强劲啊,回头想看看源代码,呵呵

本文出自 “sunfish 翻车鱼” 博客,请务必保留此出处http://sunfish.blog.51cto.com/417500/142577

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值