什么是字符集
字符集是一个系统支持的所有抽象字符的集合。
是各种文字和符号的总称。
常见的字符集种类: ASCII 字符集、GBK 字符集、Unicode字符集等。
不同的字符集规定了有限个字符:
ASCII 字符集只含有拉丁文字字母,
GBK 包含了汉字,
Unicode 字符集包含了世界上所有的文字符号。
字符集与字符编码是什么关系?
ASCII:字符集,字符编码的起源
世界上第一台计算机 1945年 由美国宾夕法尼亚大学的两位教授-莫奇利和埃克特设计和研制出来,美国人起草了计算机的第一份字符集和编码标准,叫 ASCII(American Standard Code for Information Interchange,美国信息交换标准代码),一共规定了 128 个字符及对应的二进制转换关系,128 个字符包括了可显示的26个字母(大小写)、10个数字、标点符号以及特殊的控制符,也就是英语与西欧语言中常见的字符,这128个字符用一个字节来表示绰绰有余,因为一个字节可以表示256个字符,所以当前只利用了字节的7位,最高位用来当作奇偶校验。
ASCII字符集
是字母、数字、标点符号以及控制符(回车、换行、退格)等组成的128个字符。
ASCII字符编码
是将这128个字符转换为计算机可识别的二进制数据的一套规则(算法)。
通常 字符集同时定义了一套同名的字符编码规则,例如 ASCII 就定义了ASCII 字符集以及ASCII 字符编码;
也不绝对,比如 Unicode 就只定义了字符集,而对应的字符编码是 UTF-8,UTF-16。
EASCII:扩展的ASCII
计算机开始被西欧等国家使用,西欧语言中还有很多字符不在 ASCII 字符集中,这给他们使用计算机造成了很大的限制,于是他们想办法把 ASCII 字符集扩充,ASCII 只使用了字节的前 7 位,如果把第八位也利用起来,可表示的字符个数就是 256。这就是后来的 EASCII(Extended ASCII,延伸美国标准信息交换码)
EASCII 码比 ASCII 码扩充出来的符号包括表格符号、计算符号、希腊字母和特殊的拉丁符号。
GB2312/GBK/GB18030 汉字编码
GB2312:满足了国人需求的字符集
计算机开始普及到了中国,但面临的一个巨大的问题就是汉字博大常用汉字有3500多个,远远超出了 ASCII 字符集所能表示的字符范围,即便是 EASCII 。
1981 年国家标准化管理委员会定了一套字符集叫 GB2312 ,每个汉字符号由两个字节组成,理论上它可以表示65536个字符,不过它只收录了7445个字符,6763个汉字和682个其他字符,同时它能够兼容 ASCII,ASCII 中定义的字符只占用一个字节的空间。
兼容:兼容ASCII。
GB2312 收录的汉字已覆盖中国大陆99.75%的使用频率,但对一些罕见的字和繁体字还有很多少数民族的字符都无法处理,于是就在 GB2312 的基础上创建了一种叫 GBK 的字符编码,
GBK :
GBK 不仅收录了27484 个汉字,同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。GBK 是利用了 GB2312 中未被使用的编码空间上进行扩充,
兼容:完全兼容 GB2312和 ASCII。
GB18030
GB18030 是现时最新的字符集,兼容 GB2312-1980 和 GBK, 共收录汉字70244个,多字节编码,每个字符可以有1、2、4个字节组成,某种意义上它能容纳161 万个字符,包含繁体汉字以及日韩汉字。
兼容:单字节与ASCII兼容,双字节与GBK兼容。
Unicode :一统江湖的牛B字符集
世界上还有很多国家拥有自己的语言和文字,比如日本用 JIS,台湾用 BIG5,不同国家之间交流起来就很困难,因为没有统一的编码标准,可能同一个字符,在A国家用两字字节存储,而到了B国家是3个字节,这样很容易出现编码问题。
1991 年,国际标准化组织和统一码联盟组织各自开发了 ISO/IEC 10646(USC)和 Unicode 项目,这两个项目的目的都是希望用一种字符集来统一全世界所有字符。Unicode 这一名字比较好记,因而它使用更为广泛,成为了事实上的统一编码标准。
Unicode 是一个囊括了世界上所有字符的字符集,其中每一个字符都对应有唯一的编码值(code point),注意了!注意了。它不是字符编码,仅仅是字符集而已。。
Unicode 字符如何进行编码,可以是 UTF-8、UTF-16、甚至用 GBK 来编码。
Unicode本身并没有规定一个字符究竟用一个还是三个或者四个字节表示 。
Unicode 只规定了每个字符对应到唯一的代码值(code point),代码值 从 0000 ~ 10FFFF 共 1114112 个值 。
真正存储的时候需要多少个字节是由具体的编码格式决定的。
比如字符 「A」
用 UTF-8 的格式编码来存储就只占用1个字节,
用 UTF-16 就占用2个字节,
用 UTF-32 存储就占用4个字节。
UTF( Unicode Transformation Format)编码 是 Unicode的编码方式,UTF 常见的种类有 UTF-8、UTF-16、UTF-32。
UTF-16 是变长的,遇到两个字节没法表示时,会用4个字节来表示;
UTF-32 使用4个字节表示,显然这种方式浪费的空间比较多。
UTF-8 以单字节为单位用 1~4 个字节来表示一个字符.
从首字节就可以判断一个字符的UTF-8编码有几个字节。
如果首字节以0开头,肯定是单字节编码,
如果首字节以110开头,肯定是双字节编码,
如果首字节是1110开头,肯定是三字节编码,
以此类推。除了单字节外,多字节UTF-8码的后续字节均以10开头。
UTF-8 兼容了ASCII,在数据传输和存储过程中节省了空间,
UTF-8 不需要考虑大小端问题。这两点都是 UTF-16 的劣势。
不过对于中文字符,用 UTF-8 就要用3个字节,而 UTF-16 只需2个字节。
UTF-16 的优点是在计算字符串长度,执行索引操作时速度会很快。
Java 内部使用 UTF-16 编码方案。而 Python3 使用 UTF-8。UTF-8 编码在互联网领域应用更加广泛。
为什么 UTF-8 不需要考虑大小端问题?
UTF-8 的编码单元是1个字节,所以就不用考虑字节序问题。而 UTF-16 是用 2个字节来编码 Unicode 字符,编码单位是两个字节,因此需要考虑字节序问题,因为2个字节哪个存高位哪个存低位需要确定。
总结
字符编码本质上是字符到字节的转换过程
字符集的演进过程是:ascii、eascii、ISO 8859-x、gb2312、Unicode
Unicode 是字符集,对应的编码格式有UTF-8,UTF-16
字节序列存储的时候有大小端之分