工作中经常遇到中文乱码的问题,由于历史的原因,工作中经常遇到文件编码不一致的情况。老员工之前使用的是gbk编码,新来的拿到之前的代码,用utf8编码打开,就会出现乱码,我就经常遇到这样的情况。不同系统间传递文件也会出现乱码的情况,比如苹果系统打开windows系统的文件,也会有乱码。今天来学习一下计算机字符编码的相关知识。
ASCII码
基本的ASCII码有128个字符,包括96个可打印字符和32个控制字符。使用7个二进制位对字符进行编码,对应的ISO标准为ISO646标准。A的ASCII码为65,0为48,a为97等。由于计算机基本处理单位是字节(8个二进制位),所以用一个字节来存储ASCII码,最高位通常为0。
扩展ASCII码与标准ASCII码保持兼容,扩充了(128~255)128个字符。一共可以表示256个字符。
无论是ASCII码还是扩展ASCII码,都无法对上万个的汉子进行编码。
GB2312编码
GB2312是1980年发布的,标准号为GB2312-1980,也被称为国标码。几乎所有的中文系统和国际化的软件都支持该编码。由6763个汉子和682个全角的字符组成。其中一级汉子3755个,二级汉子3008个。GB2312采用二维矩阵法对所有字符进行编码,矩阵大小为94 x 94,可以表示8836种情况,每一行为区,每一列为位,区位确定了唯一的位置,称为字符的区位码。区位分别用一个字节表示,所以中文字符需要占用两个字节。为了区分是中文编码还是西文字符,需要每个字节分别加上160的方法转换为存储码,计算机存储的是此编码的补码,位码在前,区码在后。
GB2312编码用两个字节表示一个汉字,理论上可以表示65536个汉字。
但上面说到GB2312采用94 x 94的矩阵,表示7000多个字符。
GBK编码
GBK编码标准兼容GB2312,共收录汉字21003多个,符号883个。GBK的出现弥补了GB2312的不足。GBK采用双字节表示,首字节在81-FE之间,尾字节在40-FE之间,去除xx7F一条线。苹果OS以GB2312为基本汉字编码,windows以GBK为基本汉字编码。
Big5编码
也称大五码,是一种繁体中文汉字字符集编码,与GB2312编码范围存在冲突,不能同时支持两种字符集的字符。Big5编码成为繁体中文编码的事实标准,在台湾,香港,澳门以及其他海外华人中普遍使用。
ANSI编码
不同的国家和地区制定了不同的标准,由此产生了GB2312,GBK,Big5,等各自的编码标准,这些用1至4个字节来表示一个字符的各种汉字延伸编码方式称为ANSI编码,在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码;在日文Windows操作系统中,ANSI 编码代表 Shift_JIS 编码。不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。 当然对于ANSI编码而言,0x00~0x7F之间的字符,依旧是1个字节代表1个字符。这一点是ANSI编码与Unicode编码之间最大也最明显的区别。
Unicode编码
如上ANSI编码条例中所述,世界上存在着多种编码方式,在ANSi编码下,同一个编码值,在不同的编码体系里代表着不同的字。在ANSI编码体系下,要想打开一个文本文件,不但要知道它的编码方式,还要安装有对应编码表,否则就可能无法读取或出现乱码。为什么电子邮件和网页都经常会出现乱码,就是因为信息的提供者可能是日文的ANSI编码体系和信息的读取者可能是中文的编码体系,他们对同一个二进制编码值进行显示,采用了不同的编码,导致乱码。这个问题促使了unicode码的诞生。
如果有一种编码,将世界上所有的符号都纳入其中,无论是英文、日文、还是中文等,大家都使用这个编码表,就不会出现编码不匹配现象。每个符号对应一个唯一的编码,乱码问题就不存在了。这就是Unicode编码。
UTF-8
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码,由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编码Unicode字符。用在网页上可以统一页面显示中文简体繁体及其它语言。
如果UNICODE字符由2个字节表示,则编码成UTF-8很可能需要3个字节。而如果UNICODE字符由4个字节表示,则编码成UTF-8可能需要6个字节。用4个或6个字节去编码一个UNICODE字符可能太多了,但很少会遇到那样的UNICODE字符。UTF-8编码规则:如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的字节数,其余各字节均以10开头。
Base64编码
Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。
转码过程例子:
3*8=4*6
内存1个字节占8位
转前: s 1 3
先转成ascii:对应 115 49 51
2进制: 01110011 00110001 00110011
6个一组(4组) 011100110011000100110011
然后才有后面的 011100 110011 000100 110011
然后计算机是8位8位的存数 6不够,自动就补两个高位0了
所有有了 高位补0
科学计算器输入 00011100 00110011 00000100 00110011
得到 28 51 4 51
查对下照表 c z E z
大小端模式
大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;这和我们的阅读习惯一致。
小端模式,是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低。