字符在utf-8,gbk,gb2312,iso8859-1下的編碼實驗

一直以來對編碼並不是太理解,所以用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);方法很強勁啊,回頭想看看源代碼,呵呵
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章