一、字符编码的发展历程java
①、ASCII 码数组
由于计算机只认识数字,因此咱们在计算机里面的一切数据都是以数字来表示,由于英文字符有限,因此规定使用的字节的最高位是 0,每个字节都是以 0-127 之间的数字来表示。好比 A 对应 65,a 对应 97。这即是 美国标准信息交换码,ASCII服务器
String str = new String("Aa"); byte[] strASCII = str.getBytes("ASCII"); System.out.println(Arrays.toString(strASCII));//[65, 97]
②、GB2312 码网络
随着计算机在全球的普及,不少国家和地区都把本身的字符引入了计算机,好比汉字。此时发现一个字节能表示的数字范围过小,不能包含全部的中文汉字。那么就规定使用两个字节来表示一个汉字。编码
规定:原有的 ASCII 字符的编码保持不变,仍然使用一个字节表示,为了区别一个中文字符与两个 ASCII 码字符相区别。中文字符的每一个字节最高位规定为 1(即中文的二进制是负数),这即是 GB2312 编码计算机网络
String str = new String("Aa帅锅"); byte[] strASCII = str.getBytes("GB2312"); System.out.println(Arrays.toString(strASCII));//[65, 97, -53, -89, -71, -8]
③、GBKcode
因为中国汉字太多,在 GB2312 的基础上增长了更多的中文字符,这种编码是 GBKblog
问题:若是只是在中国,那么你们都认识汉字,可是若是是别的国家,而该国家的码表中是没有收录汉字的。那么计算机在显示的时候就为乱码或是别的字符字符串
解决办法:为了解决各个国家由于本地化字符编码带来的影响,就把全世界全部的字符统一进行编码---Unicode 编码get
此时某一个字符在全世界任何地方显示都是固定的,好比汉字 哥,在任何地方都是以十六进制 54E5 来表示。
Unicode 的字符编码都占有两个字节
④、UTF-8
是一种针对 Unicode 的可变长度字符编码,又称为 万国码,是 Unicode 的实现方式之一。编码中的第一个字节仍与 ASCII 兼容,这使得原来处理 ASCII 字符的软件无须或只需作少部分修改,便可继续使用。所以,它逐渐成为电子邮件、网页及其余存储或传送文字的应用中,优先采用的编码。互联网工程工做小组(IETF)要求全部互联网协议都必须支持 UTF-8 编码
String str = new String("Aa帅锅"); byte[] strASCII = str.getBytes("UTF-8"); 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 数组转换为 字符串
注意:①、编码格式和解码格式必须一致,不然乱码
String str = new String("Aa帅锅"); //编码操做 byte[] strByte = str.getBytes("GBK"); System.out.println(Arrays.toString(strByte));//[65, 97, -53, -89, -71, -8] //解码操做 //注意编码的字符集和解码的字符集格式必须一致(是其扩展字符集也能够),不然会乱码 //第一种:编码格式为 GBK,解码格式为 ISO-8859-1 那么就会乱码 String str2 = new String(strByte,"ISO-8859-1"); System.out.println(str2); //Aa?§?? //第二种:编码和解码格式一致 String str3 = new String(strByte,"GBK"); System.out.println(str3); //Aa帅锅
②、有时候编码为和解码格式一致了,可是仍是乱码,这是由于在数据在传输过程当中通过服务器的处理,而这个服务器多是外国人编写的,那么就会将数据转换为 别的字符格式,那么你若是仍是直接转为本身想要的格式是会乱码的。
解决办法:先获取通过服务器以后的数据还原编码,而后在进行解码
String str = new String("Aa帅锅"); //编码操做 byte[] strByte = str.getBytes("UTF-8"); System.out.println(Arrays.toString(strByte));//[65, 97, -27, -72, -123, -23, -108, -123] //中间通过了服务器的传输,编码格式转成了 ISO-8859-1 String str2 = new String(strByte,"ISO-8859-1"); //解码操做 ,此时若是直接进行解码,那么会乱码 String str3 = new String(str2.getBytes(),"UTF-8"); System.out.println(str3); //Aa??????? //对于上面的乱码,咱们必须先还原服务器以前的编码格式,而后在进行解码。那么就不会乱码 byte[] strByte2 = str2.getBytes("ISO-8859-1"); String str4 = new String(strByte2,"UTF-8"); System.out.println(str4); //Aa帅锅