引言

美国在最早计算机刚发明出来时,计算机的字符输入是通过一堆点集输入的,
因为最早需要存储的内容类型不多,就英文字母(大小写)、数字、标点符号、特殊符号,一共128个字符,这些用于表示字符编号(0-127)的就叫做:码点 即一个字符对应一个码点,这一整套就是最早的标准ASCII字符集

ASCII字符集

引言中提到了由来,在计算机中,0-127 转成二进制只有7位:127 => 1111111,但计算机底层存储单位是以字节为单位的,1个字节8位,所以就在原7位的基础上在最左边添加一位0:127 => 01111111

  • ASCII:美国信息交换标准代码,报告了英文、符号等。
  • 标准ASCII使用1个字节存储一个字符,首尾是0,总共可表示128个字符,对美国来说够用

GBK字符集

随着发展,因为ASCII码不支持汉字,中国也对汉字编码进行了规范,这就是GBK,GBK采用2个字节表示汉字,英文字符仍为1个字节,因为可能出现中英文交叉的内容,为了计算机能正确识别哪两个字节是表示汉字,哪一个字节表示字符,GBK规定:汉字的第一个字节的第一位必须是1。形象展示如下:“我a你 ==> xxxxxxxx xxxxxxxx 0xxxxxxx xxxxxxxx xxxxxxxx ==> 1xxxxxxx xxxxxxxx 0xxxxxxx 1xxxxxxx xxxxxxxx”

  • GBK:汉字编码字符集,包含了2万多个汉字等字符,GBK中一个中文字符编码成两个字节的形式存储
  • 注意:GBK兼容了ASCII字符集

Unicode字符集

各国都制订自己国家语言的字符集,于是国际组织制定了Unicode字符集,可以容纳世界上所有文字、符号的字符集。

  • UTF-32:统一使用4个字节来表示各种字符,xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 占存储空间,通信效率变低

UTF-8

utf-32的种种缺点,于是乎,UTF-8出来了, 他是Unicode字符集的一种编码方案,采取可变长编码方案,共分四个长度区:1个字节,2个字节,3个字节,4个字节

  • UTF-8:兼容ASCII码,英文字符和数字占一个字节,汉字占3个字节
UTF-8编码方式 二进制编码格式
一个字节 0xxxxxxx (对应ASCII码)
两个字节 110xxxxx 10xxxxxx
三个字节 1110xxxx 10xxxxxx 10xxxxxx
四个字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

JAVA中编码和解码

注意: 使用什么编码就使用什么解码

编码:将字符编码成字节数组,String 提供了如下方法:

方法 说明
byte[] getBytes() 使用平台的默认字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
byte[] getBytes(String charsetName) 使用指定的字符集将此 String 编码为 byte 序列,并将结果存储到一个新的 byte 数组中。

解码:将 字节数组 转换为 字符串

方法 说明
String(byte[] bytes) 根据平台默认字符集将指定的 byte 数组转换为 String。
String(byte[] bytes, String charsetName) 根据指定的字符集将指定的 byte 数组转换为 String。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.xnj;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;

/**
* 用什么编码就用什么解码
*/
public class CharSetDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
String data = "a我b";

// 1.编码
// 1.1 无参函数默认按编辑器的编码方式utf-8
byte[] bytes = data.getBytes();
System.out.println(Arrays.toString(bytes));// [97, -26, -120, -111, 98]

// 1.2 指定编码
byte[] bytes2 = data.getBytes("GBK");
System.out.println(Arrays.toString(bytes2));// [97, -50, -46, 98]

// 2.解码
// 2.1 无参函数默认按编辑器的编码方式utf-8解码
String str1 = new String(bytes);
System.out.println(str1);// a我b
String str3 = new String(bytes2);
System.out.println(str3);// a��b 发生乱码

// 2.2 指定编码
String str2 = new String(bytes2, "GBK");
System.out.println(str2); // a我b
}
}