前言 
我想,对于软件开发人员来说,“编码”这个概念一定不陌生,甚至说“经常接触”,在我们写代码的过程中,“编码问题”是一个让我们程序员无奈又头疼的问题。

“编码问题”解决起来并不难,但原理,我相信有很多程序员都是似是而非,那接下来我们就一起来探讨一下这个问题。

计算机编码 
计算机编码指电脑内部代表字母或数字的一种记录数据的方式。

为什么会出现编码?我们知道,计算机中的数据是由电子原件存储的,而因为工业技术的限制,电子元件只能记录两种稳定状态“开”和“关”,用数字来表示,就是0 和1。也就是说,本质上计算机只能记录0和1这两个数字。每个0或者1,我们称之为一个bit,是计算机最小的单位。这种只有0和1的数字,我们称之为2进制数字。

但很明显,我们需要记录的东西很多,所以只有两个数字肯定不行,于是3个bit共同来表示一位数字,就有了8进制。4个bit共同来表示一位数字,就有了16进制。

数字问题解决了,但是,如果想在计算机中存储一个字符‘a’,却无法做到。为了解决这个问题,人们就想了一种解决方法:把所有的常用的字符都统一编号,如‘a’的编号就是97,这样,当我们需要存储‘a’的时候,不直接存储‘a’,而是存储数字97,当拿出来的时候,再把这个97变成‘a’,这样就完美解决了这个问题。

而我们通常所说的“编码”就是这些字符的编号。

所有字符的和其编号对应的表格,我们称之为“编码表”。

常见的编码表:ASCII编码,GB2312编码(简体中文),GBK,BIG5编码(繁体中文),utf-8编码等

ASCII编码:
计算机在创建之初,流行于“西方世界”或者叫“英语国家”,拆开来看,西方世界的语言、文字等等,充其量也就是26个英文字母加上一些符号,即使英文字母分大小写,也绝不超过128个,每个字符使用一个字节来表示,足够了。使用一个字节来表示一个字符的这种编码方式,就是最早的:ASCII编码。

注1:字节是由8个bit组成的一个基本单位,表示的范围是:-128---127

注2:编码没有负数

注3:ASCII不支持中文。

 

 

 

GBK编码:
后来,随着计算机的普及,整个世界都需要使用计算机来存储数据,如果还使用ASCII编码肯定不行(无法存储罗马字母表以外的字符),而且ASCII编码所规定的一个字节表示一个字符的这种规定很明显无法适用于整个世界(汉字至少也要几千个吧)。所以,各国都对ASCII编码进行了扩充,由原来的一个字节表示一个字符,转换为多个字节表示一个字符。

例如中国的GB2312,GBK两种编码格式,都是2个字节来表示一个字符。当然两个字节所能表示的范围就大了,几乎所有的常用汉字都可以被包括了。

注:不管是什么编码,但是最初的0-127范围之内所表示的字符和ASCII编码都完全一致。

UTF-8编码:
当然,如果世界各国都使用自己的编码,那国家与国家之间的交流就比较麻烦,比如本来在你这里是赞扬的意思,到了对方那里,因为编码不同,解析出来是骂人的意思,这就不行了。所以,为了解决这个问题,由一个名为 Unicode 学术学会的组织,制订了一套编码规则-Unicode编码。该规则支持世界上超过650种语言。是一种世界通用字符规则。

UTF-8就是按照这种规则推出的一种国际性编码表。

UTF-8是国际性编码表,支持中文编码。中文在该编码表中一般占用3个字节

注1:Unicode编码并不是一种编码表,而是一种编码规则。UTF-8才是编码表,UTF-8就是根据这种规则指定出来的编码表

注2:UTF-8中的中文不全是3个字节,常用的占用3个字节,一些特殊的,非常罕见的字可能会占用6个字节。

 

编码问题:
开发中,所谓的“编码问题”,其实就是出现了中文乱码。为什么出现这种问题呢?

我们中国人,一般使用的都是中文的操作系统,而中文操作系统默认的编码格式是GBK。而国际上,为了全世界都能看懂,则一般使用UTF-8编码。(国际性网站一般都是UTF-8编码)

GBK编码,一个汉字一般占用2个字节。

UTF-8编码,一个汉字一般占用3个字节。

 

如果是:UTF-8 --> GBK

 

 

 

 

如果是:GBK --> UTF-8

 

 

解决编码问题:
“编码问题”的出现,无非是我们在解析别人给我们汉字的时候,使用的编码出错了,如果我们拿到的是GBK,就使用GBK解析,如果拿到的是UTF-8,就是使用UTF-8解析,这样不就解决了么?

所以,如果是遇到字符串出现中文乱码:

1.把中文乱码字符串重写打散,变为字节。

2.使用String的构造函数String(byte[] bytes, String charsetName)重组字符串。

 

例如:   UTF-8解析

 

 

注:中文乱码只是因为我们在对字节解析的时候,组装错误了,就类似于玩积木的时候,放错位置了,但本质的字节没有改变。