字符集你知多少?

ASCII

ASCII(American Standard Code for Information Interchange):美国信息交换标准代码,包括了英文、符号等。
● 标准ASCII使用1个字节(8位)存储一个字符,首位是0,总共可表示2^7=128个字符,对美国佬来说完全够用。

GBK (汉字内码扩展规范,国标)

汉字编码字符集,包含了2万多个汉字等字符, GBK中一个中文字符编码成两个字节(16位)的形式存储一个字符,
● 汉字的第一个字节的第一位必须是1,总共可以表示 2^15 = 32768个字符
注意: GBK兼容了ASCII字符集。
中文字符第一个字节的第一个位是1 而ASCII的第一位是0 因此 GBK兼容ASCII时 可以通过首位是1还是0来区分
我a你
1XXXXXXX XXXXXXXX 0XXXXXX 1XXXXXXX XXXXXXXX

Unicode (统一码, 也叫万国码)

Unicode是国际组织制定的,可以容纳世界上所有文字、符号的字符集。
UTF-32 4个字节(32位)
4个字节表示一个字符 奢侈! 占存储空间,通信效率变低!
一个英文字符只使用1个字节 01100001 还需要在前边补充 3个字节 00000000 00000000 00000000 01100001
一个中文字符只使用2个字节 01100001 01100001 还需要在前边补充 2个字节 00000000 00000000 01100001 01100001
● 基本上不考虑使用该字符集

UTF-8 (Unicode字符集的一种编码方案)

UTF-8 ● 注意:技术任意在开发时都应该使用UTF-8编码
是Unicode字符集的一种编码方案,采取可变长编码方案,共分四个长度区: 1个字节, 2个字节,3个字节, 4个字节
英文字符、数字等只占1个字节(兼容标准ASCII编码),汉字字符占用3个字节。
0XXXXXXX | XXXXXXXX XXXXXXXX XXXXXXXX 0XXXXXXX
UTF-8编码方式(二进制)
一个字节 0xxxxxxx (ASCII码) 第一位必须是0
两个字节 110xxxxx 10xxxxxx 第一个字节必须以110开头
三个字节 1110xxxx 10xxxxxx 10xxxxxx 第一个字节必须以1110开头
四个字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 第一个字节必须以11110开头
a 97 (ASCII) 01100001 (UTF-8)
我 25105 (GBK) 1110 001000 01001 (UTF-8)
m 109 (ASCII) 01101101 (UTF-8)
a我m 01100001 | 1110 001000 010001 | 01101101 解码的时候通过第一个字节的开头 即可区分是什么字符

小总结

● ASCII字符集:只有英文、数字、符号等,占1个字节。
● GBK字符集:汉字占2个字节,英文、数字占1个字节。
● UTF-8字符集:汉字占3个字节,英文、数字占1个字节。
!!! 注意1:字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码
!!! 注意2:英文,数字一般不会乱码,因为很多字符集都兼容了ASCII编码。

java进行编码和解码

Java对字符的编码
String提供了如下方法
byte[] getBytes() 使用平台的默认字符集将该String编码为一系列字节,将结果存到新的字节数组中
byte[] getBytes(String charsetName) 使用指定的字符集将该String编码为-系列字节 ,将结果存到新的字节数组中

Java对字符的解码
String提供了如下方法
String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组来构造新的String
String(byte[] bytes, String charsetName ) 通过指定的字符集解码指定的字节数组来构造新的String

代码示例
public class EncodingSimpleTest {
    /**
     * 编码
     */
    @Test
    public void test () throws UnsupportedEncodingException {

        System.out.println("----------------编码-----------------");
        //utf8中英文占1个字节 中文占3个字节 共计5个字节
        String s = "a我b";
        //默认按照平台字符集进行编码 我的设置编码默认是utf8
        byte[] utf8Bytes = s.getBytes();
        //Arrays.toString(bytes) = [97, -26, -120, -111, 98]  在二进制中第一位是1 表示负数 第一位是0表示正数 中文都是1打头 因此三个字节都是负数
        System.out.println("Arrays.toString(bytes) = " + Arrays.toString(utf8Bytes));

        //按照指定字符集进行编码 GBK 英文占以个字节 中文占2个字节 共计占4个字节
        byte[] gbkBytes = s.getBytes("GBK");
        System.out.println("bytes1.toString() = " + Arrays.toString(gbkBytes));



        System.out.println("----------------解码-----------------");
        System.out.println("默认使用平台字符集解码 输出a我b = " + new String(utf8Bytes));

        System.out.println("gbkBytes用GBK编码 但使用默认字符集utf8解码 因此输出乱码 = " + new String(gbkBytes));

        System.out.println("指定解码字符集 输出a我b = " + new String(gbkBytes, "GBK"));

    }
}

你可能感兴趣的:(java)