编码、解码、乱码原理

一.解码和编码

解码:就是把能看得懂的转成二进制字节码文件(字节-------->字符)

编码:就是把二进制字节码文件转成能看得懂的文字(字符-------->字符节)
编码表:字典。人们生活中常用的字符与计算机二进制之间的对应关系表

ASCII:美国定义的一张码表。这张码表中只有:数字、字母、符号、拉丁文。用1个字节的最低7位表示数据
生活中的字符             十进制                 二进制
          a                             97                 01100001

ISO8859-1:欧洲的一张码表,兼容ASCII,增加了欧洲语言。一个字节表示一个字符,所有8位都表示数据

这张码表中没有未知字符。全部所有数字都有对应的符号

GB2312:兼容ASCII,识别数千中文,2个字节表示一个字符。
GBK:是GB2312的升级版,识别2万多中文,2个字节表示一个字符。
GB18030:是GBK的升级版,包含了大部分的中文,还有少数民族的文字。2个字节

Unicode:世界计算机协会制定通用码表,2个字节表示一个字符。
UTF-8:Unicode升级版。能用1个字节表示的就用1个字节,要用两个字节的就用2个字节,能用3个字节表示的就用3个字节。汉字基本都是3个字节


二.问题

在win7自带的记事本写入"联通"俩个字,再次打开就会乱码,这是为什么呢?




原因是:你保存的时候是ASII格式,再次打开的时候是UTF-8格式。

存储在硬盘上的都是二进制字节码,第一次写入联通时,记事本进行了编码,这时使用的是ASII编码格式。第二次打开的时候,把二进制字节码文件解码成字符串,只不过这次使用的是UTF-8的格式解码。编码和解码使用编码集不同导致的。

解决方法:写入的时候保存为UTF-8的格式。

三.案例


代码实现

package cn.jasonEncodeAndDecode;

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

/**
 * 乱码会导致丢码,丢失数据
 * 
 * @author Jason
 */
public class Code {
	public static void main(String[] args) throws UnsupportedEncodingException {
		// 编码
		encode();
		// 解码
		decode();
		// 乱码
		wrongCode();
	}

	private static void wrongCode() throws UnsupportedEncodingException {
		String s = "你好";
		byte[] bytes = s.getBytes("UTF-8");
		String string = new String(bytes, "GBK");
		// 输出浣犲ソ,由于编码和解码的码表不同导致
		System.out.println(string);

		// 拨乱反正
		byte[] bytes2 = string.getBytes("GBK");
		String string2 = new String(bytes2, "UTF-8");
		// 输出你好
		System.out.println(string2);

	}

	private static void decode() throws UnsupportedEncodingException {
		// String(byte[] bytes, Charset charset) 通过使用指定的 charset 解码指定的 byte
		// 数组,构造一个新的 String。
		// 把看不懂的转成看的懂的,就是把字节转换成字符
		String s = new String(new byte[] { -60, -29, -70, -61 }, "GBK");
		// 输出你好
		System.out.println(s);

		String s1 = new String(new byte[] { -60, -29, -70, -61 }, "UTF-8");
		// 输出???,平台默认是GBK,UTF-8是三个字节是一个字符,转换异常
		System.out.println(s1);

		String s2 = new String(new byte[] { -60, -29, -70, -61 }, "ISO8859-1");
		// 输出????,平台默认是GBK,ISO8859-1是一个字节是一个字符,转换异常,欧洲码表没有负数
		System.out.println(s2);

	}

	private static void encode() throws UnsupportedEncodingException {
		String s = "你好";
		// 使用平台默认的编码集,也就是eclipse的GBK编码[-60, -29, -70, -61]默认GBK
		byte[] bytes = s.getBytes();
		System.out.println(Arrays.toString(bytes));

		// GBK一个字符是两个字节 [-60, -29, -70, -61]
		byte[] bytes1 = s.getBytes("GBK");
		System.out.println(Arrays.toString(bytes1));

		// UTF-8就是[-28, -67, -96, -27, -91, -67],一个字符是3个字节
		byte[] bytes2 = s.getBytes("UTF-8");
		System.out.println(Arrays.toString(bytes2));
	}
}


  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值