1、ASCII
计算机和网络这东西嘛,大家都知道,发源于美国,而美国呢是用英语的,而英语呢——嗯,算着大小写,字母总共就52个,再加上些别的符号,也不会很多,当通信在美国萌芽的时候,需要表示的符号并没有多少,用8位也就足够了,标准ASCII码在这时应运而生了。每个字符它只用一个字节(即8位)来表示,说得更详细些,其实只用了最低的7位,最高位是用来做校验的。此后,这个ASCII码表示规范成为了国际标准。
举例,小写字母a,它的ASCII码用二进制来表示是 0110 0001,用十进制表示也就是97,最高位(最左一位)为0。
注意:在标准ASCII码中最高位始终是0,但是在传输时,为了奇偶校验(不懂的请百度),这一位可能会改变。
2、扩展ASCII码
好了,ASCII码已经可以表示英语里所有字符和很多其他字符了,够美国人用了,可后来呢——计算机这玩意儿越来越普及了,其他欧美国家也可以发展了,他们发现自己国家的文字在ASCII码里根本就没有,毕竟ASCII码就那么128个。好了,再扩展一下吧-----把最高位也利用起来,不用它来做奇偶校验了。于是IBM又把ASCII码一下又扩展出了128个,总共可以表示256个字符了。它把值为128-255之间的字符用于画图和画线,以及一些特殊的欧洲字符。同时,还有另一部分人,把128--255之间当做了别的用途,比如用于拉丁字母表中特殊语言字符的编码(ISOLatin-1标准)。所以,扩展出的这128个码具体表示哪个字符有多个标准,因此扩展ASCII码就不是国际标准了,没有一个统一的标准。
3、GBK
当计算机来到中国的时候,庞大的汉字数量需要一套全新的支持汉字的编码规范。
GB2312:与ASCII码兼容,也就是当表示英文字符这种ASCII码中存在的字符时,仍采用一个字节表示;当表达汉字时,采用两个字节表示,高字节叫“区”,低字节叫“位”,且区和位的首位都是1,如 10100010,11000110,这样当解析字符时一旦读到一个字节的最高位是1就知道了----后面的那个字节跟它是配对的,它俩组成一个字符-----因为当最高位是0时,肯定是原ASCII码字符。
GBK:GB2313之后发现这样编码还是不够用,那就干脆规定,“区”的最高位仍是1,“位”的最高位不限制了,因为这样也并不影响解读。于是在GB2312的基础上又扩展出了GBK规范。
GBK18030:GBK之后还是不够用,再扩展,又出了GBK18030。
4、UNICODE
再后来,越来越多国家的文字需要支持,而且各个国家自己定义的规范与别国的都是不兼容的,这时unicode出现了,它不考虑其他国家已自定义的各种规范----它要为全球定义一个通用的规范,”Universal Multiple-Octet Coded Character Set”,简称 UCS, 俗称 “UNICODE”。并且这个标准是兼容ISO Latin-1的,当然,也是兼容ASCII规范的。还以小写的a举例,在ASCII码中a的数字值是97,那么在unicode中仍规定a对应的数字是97。
刚才在百度“UNICODE”时,看到百度百科里说-----Unicode 编码包含了不同写法的字,如“ɑ/a”、“户/户/戸”,又说----在文字处理方面,统一码为每一个字符而非字形定义唯一的代码(即一个整数)。换句话说,统一码以一种抽象的方式(即数字)来处理字符,并将视觉上的演绎工作(例如字体大小、外观形状、字体形态、文体等)留给其他软件来处理,例如网页浏览器或是文字处理器。
读来读去,总觉这段话自相矛盾,既然包含了不同写法的字,那就应该是为这些不同写法的字每个都配了相应的代码吧?那后面又怎么说“为每一个字符而非字形定义唯一的代码”?它的意思大概是----大家记不记得有些特别另类的汉字,当做同一个字来用但是写起来差别特别大,这种现象好像叫“变体”。我举不出例子,但是咱就来个假设吧,例如,假设“品”字就是“码”字的变体,写“编码”正确,写“编品”也同样正确,此时“码”和“品”除了写法不一样,其他,包括字义、用法、读音全部一样。实际在unicode中就是看做是两个字了,它们有各自对应着的数字。
值得注意的一点是,unicode里的字符并不一定占用两个字节,实际上,unicode只是一个规定,它规定一个符号跟哪一个数字对应,简而言之,它用一个数字映射一个字符,但是没有规定在计算机里你怎样去保存这个数字。unicode跟字节是没有必然联系的,只是这个规范是跑在计算机上的,当这个规范实现的时候也就和字节发生了联系,因为数据在计算机里就是用字节存储的。举个例子,假设unicode规定“京”这个字对应着数字325,Unicode实现规范A可能这样在计算机里实现:用三个字节,三个字节分别表示百、十、个位,即00000011,00000010,00001010,而B则这样实现:我尽量用较少的空间表示,325超出了一个字节的表示范围,但可以用两个字节表示,于是B这样表示325----00000001,01000101,看!同样表示325,不同的实现方式就会占用不同的字节数。UTF-8,UTF-16就是unicode的不同实现,打个比方,unicode是个接口,UTF-8和UTF-16就是它的实现类。