zoukankan      html  css  js  c++  java
  • Java 字符编码与解码

    一、字符编码的发展历程

    ①、ASCII 码

      因为计算机只认识数字,所以我们在计算机里面的一切数据都是以数字来表示,因为英文字符有限,所以规定使用的字节的最高位是 0,每一个字节都是以 0-127 之间的数字来表示。比如 A 对应 65,a 对应 97。这便是 美国标准信息交换码,ASCII

    1 String str = new String("Aa");
    2 byte[] strASCII = str.getBytes("ASCII");
    3 System.out.println(Arrays.toString(strASCII));//[65, 97]

    ②、GB2312 码

      随着计算机在全球的普及,很多国家和地区都把自己的字符引入了计算机,比如汉字。此时发现一个字节能表示的数字范围太小,不能包含所有的中文汉字。那么就规定使用两个字节来表示一个汉字。

      规定:原有的 ASCII 字符的编码保持不变,仍然使用一个字节表示,为了区别一个中文字符与两个 ASCII 码字符相区别。中文字符的每个字节最高位规定为 1(即中文的二进制是负数),这便是 GB2312 编码

    1 String str = new String("Aa帅锅");
    2 byte[] strASCII = str.getBytes("GB2312");
    3 System.out.println(Arrays.toString(strASCII));//[65, 97, -53, -89, -71, -8]

    ③、GBK

      由于中国汉字太多,在 GB2312 的基础上增加了更多的中文字符,这种编码是 GBK

    问题:如果只是在中国,那么大家都认识汉字,但是如果是别的国家,而该国家的码表中是没有收录汉字的。那么计算机在显示的时候就为乱码或是别的字符

    解决办法:为了解决各个国家因为本地化字符编码带来的影响,就把全世界所有的字符统一进行编码---Unicode 编码

         此时某一个字符在全世界任何地方显示都是固定的,比如汉字 哥,在任何地方都是以十六进制 54E5 来表示。

         Unicode 的字符编码都占有两个字节

    ④、UTF-8

      是一种针对 Unicode 的可变长度字符编码,又称为 万国码,是 Unicode 的实现方式之一。编码中的第一个字节仍与 ASCII 兼容,这使得原来处理 ASCII 字符的软件无须或只需做少部分修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持 UTF-8 编码

    1 String str = new String("Aa帅锅");
    2 byte[] strASCII = str.getBytes("UTF-8");
    3 System.out.println(Arrays.toString(strASCII));//[65, 97, -27, -72, -123, -23, -108, -123]

    存储字母、数字:无论什么字符集都占有 1 个字节

    存储汉字:GBK 家族占有 2 个字节。UTF-8 占有 3 个字节

           不能使用单字节的字符集(ASCII/ISO-8859-1)来存储中文

    二、字符的编码和解码

    信息在计算机网络中传输是以字节的形式。那么如何变为字节?这就是编码的过程。那么计算机接收了这个编码,如何让使用者认识呢?那必须要将字节转换为人所识别的字符串形式,这就是解码的过程。

      编码:将字符串转换为 byte 数组

      解码:把 byte 数组转换为 字符串

    注意:①、编码格式和解码格式必须一致,否则乱码

     1 String str = new String("Aa帅锅");
     2         //编码操作
     3         byte[] strByte = str.getBytes("GBK");
     4         System.out.println(Arrays.toString(strByte));//[65, 97, -53, -89, -71, -8]
     5 
     6         //解码操作
     7         //注意编码的字符集和解码的字符集格式必须一致(是其扩展字符集也可以),否则会乱码
     8         //第一种:编码格式为 GBK,解码格式为 ISO-8859-1  那么就会乱码
     9         String str2 = new String(strByte,"ISO-8859-1");
    10         
    11         System.out.println(str2); //Aa?§??
    12 
    13         //第二种:编码和解码格式一致
    14         String str4 = new String(strByte,"GBK");
    15         //或者有另一种方式解码,从位置0开始解码,一直解码到strByte.length
    16         String str3 = new String(strByte,0,strByte.length,"GBK");
    17         System.out.println(str4); //Aa帅锅

    三、乱码情况分析

    (1)字节数不够

    String str3 = new String(strByte,0,strByte.length-1,"GBK");

    比如,末尾是一个中文,一个中文占2字节,减去一个就乱套了

    (2)字符集不统一

  • 相关阅读:
    题解 CF171G 【Mysterious numbers
    题解 P1157 【组合的输出】
    题解 P3955 【图书管理员】
    题解 P2036 【Perket】
    题解 CF837A 【Text Volume】
    题解 CF791A 【Bear and Big Brother】
    题解 CF747A 【Display Size】
    题解 P1332 【血色先锋队】
    题解 P2660 【zzc 种田】
    题解 P4470 【[BJWC2018]售票】
  • 原文地址:https://www.cnblogs.com/qiaoxin11/p/12584764.html
Copyright © 2011-2022 走看看