字符集编码
引言
美国在最早计算机刚发明出来时,计算机的字符输入是通过一堆点集输入的,
因为最早需要存储的内容类型不多,就英文字母(大小写)、数字、标点符号、特殊符号,一共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
34package 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
}
}