首先,我们要明确最基本的一点就是计算机的最小存储单位是字节(1byte=8bit)
字符集
1.什么是字符
字符是各种文字和符号的总称,包括各个国家文字标点符号,图形符号,数字等。
2.字符集
首先,我们可以说一句废话,字符集是字符的集合。
将一些特定的汉字,符号,字母收入到一个标准中,这些遵循同个标准的字符集合就称为字符集。
常见字符集有Unicode字符集,ASCII字符集,ISO 8859字符集、GB2312字符集。
编码
规定每个“字符”分别用一个字节还是多个字节存储,用哪些字节来存储,这个规定就叫做“编码”
ASCII编码
ASCII字符集只有128个字符,ASCII字符集第一次以规范标准的型态发表是在1967年,最后一次更新则是在1986年,至今为止共定义了128个字符;其中33个字符无法显示(这是以现今操作系统为依归,但在DOS模式下可显示出一些诸如笑脸、扑克牌花式等8-bit符号),且这33个字符多数都已是陈废的控制字符。控制字符的用途主要是用来操控已经处理过的文字。在33个字符之外的是95个可显示的字符,包含用键盘敲下空白键所产生的空白字符也算1个可显示字符(显示为空白)。
在ASCII编码中,单字节字符串使用一个字节存放一个字符(SBCS,Single Byte Character System)。如:”Bob123”占6个字节。
注意:ASCII编码是单字节编码,只能表示128个字符,也就是说有一位是没有用到的。没有用到的那一位是最高位。
ANSI编码
因为最开始的ASCII编码只支持英语,所以为了支持更多的语言,出现了ANSI编码,通常用两个字节来表示一个字符。 关于ANSI编码,不同的地区制定了不同的标准。为了让计算机能够表示中文字符集,出现了GB2312编码。
对于台湾繁体中文字符集,对应的编码是BIG5。
注意:不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。
GB2312
ANSI编码是兼容ASCII编码的,以表示中文字符集的GB2312编码为例。GB2312编码规定,一个小于127的字节的意义与原来相同(与ASCII码),但两个大于127的字节连在一起时,就表示一个汉字 ,也就是说当一个字节的最高位为0的时候,就代表这单个字节代表一个ASCII字符集中的字符。而想要表示一个汉字,必须要两个字节,且这两个字节的最高位都必须为1,只要字节的最高位为0,那么这个单字节就表示一个ASCII字符集中的字符。这样的设计兼容了ASCII编码,但是也导致了两个字节能表示的字符少了很多。
GBK
但是中国的汉字太多了,我们很快就就发现有许多人的人名没有办法在这里打出来,不得不继续把 GB2312 没有用到的码位找出来用上。后来还是不够用,于是干脆不再要求低字节一定是127号之后的内码,只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。结果扩展之后的编码方案被称为 “GBK” 标准,GBK 包括了 GB2312 的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。
GB18030
后来少数民族也要用电脑了,于是我们再扩展,又加了几千个新的少数民族的字,GBK 扩成了 GB18030。从此之后,中华民族的文化就可以在计算机时代中传承了。
GB 18030,全称:国家标准 GB 18030-2005《信息技术中文编码字符集》,是中华人民共和国现时最新的内码字集,是 GB 18030-2000《信息技术信息交换用汉字编码字符集基本集的扩充》的修订版。
GB 18030兼容GBK。
GB 18030 编码是一二四字节变长编码。
- 单字节,其值从 0 到 0x7F,与 ASCII 编码兼容。
- 双字节,第一个字节的值从 0x81 到 0xFE,第二个字节的值从 0x40 到 0xFE(不包括0x7F),与 GBK 标准兼容。
- 四字节,第一个字节的值从 0x81 到 0xFE,第二个字节的值从 0x30 到 0x39,第三个字节从0x81 到 0xFE,第四个字节从 0x30 到 0x39。
UNICODE字符集
广义而言的UNICODE是一种标准,定义了一个字符集以及一系列的编码规则,即UNICODE字符集以及UTF-8、UTF-16、UTF-32等编码。
UNicode字符集为每一个字符分配一个码位,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
之前已经说过:不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。UNICODE的出现就是为了解决这个问题。
关于UNICODE字符集的说法,个人还是有点疑问的。我感觉严格来说是这样的:
首先,UNICODE给每一个字符都指定了一个唯一的二进制编码,也就是每一个字符都有他对应的码位。
而UTF-8等编码,指定了字节与码位的对应关系,而并非直接指定了字节与字符集中的字符的对应的关系。
所以我对到底有没有UNICODE字符集是有疑问的,UNICODE标准中,字符集就是包含全部语言的字符,不过这一点并不影响我们对字符编码的理解。
UTF-8
一个字符的Unicode编码是确定的,但是在实际传输过程中,由于不同系统平台的设计不一定一致,以及出于节省空间的目的,对Unicode编码的实现方式有所不同。Unicode的实现方式称为Unicode转换格式(Unicode Transformation Format,简称为UTF)[1]。Unicode是字符集,它主要有UTF-8、UTF-16、UTF-32三种实现方式。UTF-8是目前主流的UNICODE字符集编码方式。
UTF-8是一种针对Unicode的可变长度字符编码,可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。它可以用来表示Unicode标准中的任何字符。
UTF-8的编码规则很简单,只有二条:
- 对于单字节的符号,字节的第一位设为0,后面7位为这个符号的Unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
- 对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的Unicode码。
下表总结了编码规则,字母x表示可用编码的位。
Unicode符号范围 | UTF-8编码方式 |
---|---|
0000 0000-0000 007F | 0xxxxxxx |
0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
说明:解读UTF-8编码非常简单。如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节。