字符集和编码(ASCII、ANSI、Unicode、UTF-8)

字符集和编码

字符集和字符编码,字符集是一系列字符代码的集合,字符代码是特定字符在某个字符集中的序号,而字符编码是在传输、存储过程当中用于表示字符的以字节为单位的二进制序列。

ASCII编码系统中,字符代码和字符编码是一致的,比如字符A,在ASCII字符集中的序号,也就是所谓的字符代码是65,存储在磁盘中的二进制比特序列是01000001(0X41,十进制也是65),另外的,如在GB2312编码系统中字符代码和字符编码的值也是一致的,所以无形之中我们就忽略了二者的差异性。而在Unicode标准中字符的编码就包括多种方案,其中包括:UCS-2、UCS-4、UTF-8、UTF-16、UTF-32。

ASCII码

ASCII码全名是American Standard Code for Information Interchange, 叫做“美国信息交换标准码”。ASCII码中,一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。ASCII码是目前最普及的一种字符编码,它扎根于我们的互联网,操作系统,键盘,打印机,文件字体和打印机等。ASCII码只适用于英文,使用其他语言需要对ASCII码扩展,这样就产生了ANSI码。

ANSI码(GB2312、GBK)

ANSI编码用0x00~0x7f (即十进制下的0到127)范围的1 个字节来表示 1 个英文字符,超出一个字节的 0x80~0xFFFF 范围来表示其他语言的其他字符。也就是说,ANSI码仅在前128(0-127)个与ASCII码相同,之后的字符全是某个国家语言的所有字符。值得注意的是,两个字节最多可以存储的字符数目是2的16次方,即65536个字符。这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。

由于不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、GB18030、Big5(台湾)、Shift_JIS(日本)、Euc-kr(韩国) 等各自的编码标准。其中GB2312:共收录了 6763 个常用的汉字和字符,满足99%的日常需求。GBK:由于有些汉字是在 GB2312 标准发布之后才简化的,GBK添加了一些人名、繁体字、日语和朝鲜语中的汉字等。GB18030:共收录七万多个汉字和字符, 它在 GBK 的基础上增加了中日韩语中的汉字 和 少数名族的文字及字符,完全兼容 GB2312,基本兼容 GBK。

不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字。为了解决不同国家ANSI编码的冲突问题,这样就产生了Unicode.

Unicode(UCS-2、UCS-4)

Unicode字符集和编码如果全世界每一个符号都给予一个独一无二的编码,那么乱码问题就会消失。这就是Unicode,就像它的名字都表示的,这是一种所有符号的编码。 Unicode标准也在不断发展,但最常用的是用两个字节表示一个字符(如果要用到非常偏僻的字符,就需要4个字节)。现代操作系统和大多数编程语言都直接支持Unicode。 但是问题在于,原本可以用一个字节存储的英文字母在Unicode里面必须存两个字节(规则就是在原来英文字母对应ASCII码前面补0),这就产生了浪费。为了既能消除乱码,又能避免浪费,这样就产生了UTF-8。

Unicode(UTF-8)

UTF-8可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度,当字符在ASCII码的范围时,就用一个字节表示,保留了ASCII字符一个字节的编码做为它的一部分,如此一来UTF-8编码也可以是为视为一种对ASCII码的拓展。值得注意的是unicode编码中一个中文字符占2个字节,而UTF-8一个中文字符占3个字节。从unicode到uft-8并不是直接的对应,而是要过一些算法和规则来转换。 在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。 用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件。

跨平台兼容

如果文本中所有字符都在 ASCII 范围内,那么其实,记事本保存的所谓的「ANSI」文件,和 ASCII 或无 BOM 的 UTF-8 是一样的。但如果需要编辑跨平台兼容的本文不建议使用记事本,可以使用Notepad++ 等专业文本编辑器保存为不带 BOM 的 UTF-8。如果需要在编码之间的互相转换推荐使用Notepad++文本工具进行转换。