什么是编码
在计算机中,所有的数据在存储和运算时,都要使用二进制数(也就是0和1两个数)表示。但是,具体使用哪些二进制数代表哪个具体的符号,每个地区都有自己约定的一套规则,这就是编码
常见编码
ASCII
ASCII ((American Standard Code for Information Interchange): 美国信息交换标准代码)是基于[拉丁字母]的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年。
它最初是美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准,后来被国际标准化组织(International Organization for Standardization, ISO)定为国际标准,称为ISO 646标准。适用于所有拉丁文字字母。
计算机一个字节(byte)有8个二进制位(bit),每个bit有0和1两种状态,因此总共可以组合256种状态。
标准ASCII 码也叫基础ASCII码,为单字节编码,使用7位二进制数(剩下的1位二进制为0)来表示所有的大写和小写字母,数字0 到9、标点符号,以及在美式英语中使用的特殊控制字符。
0~31及127(共33个)是控制字符或通信专用字符,称为控制码。
32是空格码,33~126(共95个)是字符,称为形象码。
其中48~57为0到9十个阿拉伯数字,65~90为26个大写英文字母,97~122号为26个小写英文字母,其余为一些标点符号、运算符号等。
GB2312-80
GB就是汉语拼音国标的首字母,也就是国家标准的意思,2312是套标准的一个编号,80就是年份,gb2312-80就是中国在1980年发布的一套编号为2312的国家标准编码规则《信息交换用汉字编码字符集》
共收录 7445 个字符,其中汉字 6763 个。GB2312 兼容标准 ASCII码,采用扩展 ASCII 码的编码空间进行编码,一个汉字占用两个字节,每个字节的最高位为 1。
BIG5
又称为大五码或五大码,是使用繁体中文(正体中文)社区中最常用的电脑汉字字符集标准,共收录13,060个汉字
主要为香港,台湾及澳门地区使用,是一个繁体字编码
GBK
《汉字内码扩展规范》GBK于1995年制定,兼容GB2312、GB13000-1、BIG5 编码中的所有汉字,使用双字节编码。
GBK编码,是在GB2312-80标准基础上的内码扩展规范,共23940个码位,共收录了21003个汉字。支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字。
GB18030
GB18030-2000编码标准是由信息产业部和国家质量技术监督局在2000年 3月17日联合发布的,并且将作为一项国家标准在2001年的1月正式强制执行。
B18030-2005《信息技术中文编码字符集》是我国制订的以汉字为主并包含多种我国少数民族文字(如藏、蒙古、傣、彝、朝鲜、维吾尔文等)的超大型中文编码字符集强制性标准,其中收入汉字70000余个。
UNICODE
世界上有那么多国家,那么多语言,那是不是每个地区都得自己弄一套编码规则?为了解决这一问题,万国码诞生了。
Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。
这样一来,不同地区的编码就统一了,用不同语言写的东西,都可以适用于这一套规则,这样就不会再有乱码问题了。
UNICODE通常使用两个字节来表示一个字符,原有的英文编码从单字节变成双字节,只需要把高字节全部填为0就可以。
Unicode版本
Unicode 1.0:1991年10月
....
Unicode 13.0 2020年2月18日
Unicode属于字符集,不属于编码,UTF-8、UTF-16、UTF-32等是针对Unicode字符集的编码
Unicode 的问题
Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。
比如,汉字严的 Unicode 是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说,这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。
这里就有两个严重的问题,第一个问题是,如何才能区别 Unicode 和 ASCII ?计算机怎么知道三个字节表示一个符号,而不是分别表示三个符号呢?第二个问题是,我们已经知道,英文字母只用一个字节表示就够了,如果 Unicode 统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储来说是极大的浪费,文本文件的大小会因此大出二三倍,这是无法接受的。
它们造成的结果是:1)出现了 Unicode 的多种存储方式,也就是说有许多种不同的二进制格式,可以用来表示 Unicode。2)Unicode 在很长一段时间内无法推广,直到互联网的出现。
UTF-8
UTF-8(Universal Character Set/Unicode Transformation Format)是针对Unicode的一种可变长度字符编码。
这里的关系是,UTF-8 是 Unicode 的实现方式之一。
UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
其他实现方式还包括 UTF-16(字符用两个字节或四个字节表示)和 UTF-32(字符用四个字节表示)。
UTF-8 的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
结论
解读 UTF-8 编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节
UTF-16
UTF-16是Unicode字符编码五层次模型的第三层:字符编码表(Character Encoding Form,也称为 "storage format")的一种实现方式。即把Unicode字符集的抽象码位映射为16位长的整数(即码元)的序列,用于数据存储或传递。Unicode字符的码位,需要1个或者2个16位长的码元来表示,因此这是一个变长表示。
UTF-16使用两个字节为全世界最常用的63K字符编码,不同的是,它使用4个字节对不常用的字符进行编码。UTF-16属于变长编码。
在Unicode基本多文种平面定义的字符(无论是拉丁字母、汉字或其他文字或符号),一律使用2字节储存。而在辅助平面定义的字符,会以代理对(surrogate pair)的形式,以两个2字节的值来储存。
对于中文而言,Unicode 16编码里面已经包含了GB18030里面的所有汉字(27484个字)
UTF-16比起UTF-8,好处在于大部分字符都以固定长度的字节 (2字节) 储存,但UTF-16却无法兼容于ASCII编码
UTF-32
UTF-32 (或 UCS-4)是一种将Unicode字符编码的协定,对每一个Unicode码位使用恰好32位元。其它的Unicode transformation formats则使用不定长度编码。因为UTF-32对每个字符都使用4字节,就空间而言,是非常没有效率的。特别地,非基本多文种平面的字符在大部分文件中通常很罕见,以致于它们通常被认为不存在占用空间大小的讨论,使得UTF-32通常会是其它编码的二到四倍。虽然每一个码位使用固定长定的字节看似方便,它并不如其它Unicode编码使用得广泛。
在Unicode与ISO 10646合并之前,ISO 10646标准为“通用字符集”(UCS)定义了一种31位的编码形式(即UCS-4),其编码固定占用4个字节,编码空间为0x00000000~0x7FFFFFFF(可以编码20多亿个字符)。
UCS-4有20多亿个编码空间,但实际使用范围并不超过0x10FFFF,并且为了兼容Unicode标准,ISO也承诺将不会为超出0x10FFFF的UCS-4编码赋值。由此UTF-32编码被提出来了,它的编码值与UCS-4相同,只不过其编码空间被限定在了0~0x10FFFF之间。因此也可以说:UTF-32是UCS-4的一个子集,但就现状而言,除了 UTF-32 标准包含额外的 Unicode 意涵,UCS-4 和 UTF-32 大体是相同的
Unicode标准准备把康熙字典的所有汉字放入到Unicode 32bit编码中。
为什么会出现乱码
当你使用了不同的编码表来翻译文件时,例如使用gbk编码来翻译法语编码的文件,由于gbk编码没有收录法语字符或者同样的二进制编码代表不同的字符,自然无法正确翻译,所以就出现了乱码
关于ANSI
ANSI是一种字符代码,为使计算机支持更多语言,通常使用 0x00~0x7f 范围的1 个字节来表示 1 个英文字符。超出此范围的使用0x80~0xFFFF来编码,即扩展的ASCII编码。
不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的编码标准。这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码;在繁体中文Windows操作系统中,ANSI编码代表Big5;在日文Windows操作系统中,ANSI 编码代表 Shift_JIS 编码。
参考文章
细说:Unicode, UTF-8, UTF-16, UTF-32, UCS-2, UCS-4 - Malecrab
字符编码笔记:ASCII,Unicode 和 UTF-8 - 阮一峰
浅谈编码——编码是什么? 为什么会出现乱码? - 潮享教育李老师
编码,ASCII,Unicode,UTF-8,UTF-16,UTF-32 - 百度百科
网友评论