你了解字符集、字符编码吗?

  • ASCII: 使用一个字节表示一个字符,实际使用的只有一个字节的低7位,第8位永远是0,因此最多只能表示2^7=128个字符,主要用来表示基础的拉丁字符,如英文字母,数字等,包括95个可打印字符和33个控制字符;
  • ISO 8859-n(n=1,2,3…11,13…16,没有12): 利用了ASCII字符集没有使用的最高位,使最多可表示的字符扩展到2^8=256个字符,可以支持许多欧洲国家的语言文字;
    • 其中0x00 ~ 0x7f范围是与ASCII兼容的
    • 0x80 ~ 0xff范围是在ASCII基础上的扩展字符集
    • ISO 8859-n 字符集有多个系列,分别用于不同的欧洲语言地区,如西欧,北欧,东欧
    • Latin-1是ISO 8859-1的别名
  • GB2312: 为了表示更大规模的汉字字符集,我国制定了国家简体中文字符集,即GB2312,使用一个字节表示拉丁字母来兼容ASCII,汉字使用两个字节表示,因此GB2312是变字节的字符集,但除了简体汉字外,还有繁体汉字及中日韩文字需要表示,因此还有BIG5,GBK,GB18030几种字符集,请看下表它们的区别;
  GB2312 BIG5 GBK GB18030
作用 国家简体中文字符集 统一繁体字符集 GB2312扩展,加入对繁体字的支持 中日韩文字编码
字节数 变字节:1字节 - 兼容ASCII 2字节 - 汉字 2字节 2字节 变字节:1字节 - 兼容ASCII 2字节,4字节
范围 能表示7445个符号,包括6763个汉字 能表示21886个符号 能表示21886个符号 能表示27484个符号
兼容性 兼容ASCII, 0x00 ~ 0x7F 与ASCII保持一致 兼容ASCII,但与GB2312有冲突 兼容GB2312 兼容GB2312
  • Unicode: 终极字符集,全世界通用,用4个字节表示一个字符,可以表达的字符数理论上可达21亿左右个。但每个字符用4个字节表示总觉得有些浪费啊,毕竟字节是要占存储空间的啊,还有一个问题是如何让计算机了解你是在用4个字节表示一个字符而不是4个ASCII表示4个字符 ,这两个问题一直困扰着Unicode的发展推广。
  • UTF-8: 直到出现UTF-8解决这两个问题,UTF-8不是一种字符集,而是对Unicode字符集的一种实现,这也意味着Unicode有其他实现方式,如UTF-16,UTF-32。而如此牛逼的UTF-8,话说当初是大神Ben Thomason吃饭的时候在一张餐巾纸上设计出来的!!UTF-8的实现规则如下:
    • 对单字节字符,字节的第一位为0,后7位为该字符实际的Unicode码,所以对于拉丁字母,UTF-8与ASCII一致。
    • 对于n(n > 1)字节字符,第一个字节前n位都设为1,第n + 1位为0,后面字节的前两位均为10,剩下没有提及的位,就是字符的Unicode编码;
    • 另外需要注意的是:UTF-8与GBK,GB2312这些汉字编码完全不兼容的。
    • UTF-8字符编码理论可以表示的字符总数为:2^7 + 2^11 + 2^16 + 2^21 = 2164864, 两百多万个!!!

常见问题及解答

1.windows Notepad中的编码ANSI保存选项,代表什么含义?

ANSI是windows的默认的编码方式,对于英文文件是ASCII编码,对于简体中文文件是GB2312编码(只针对Windows简体中文版,如果是繁体中文版会采用Big5码)。所以,如果将一个UTF-8编码的文件,另存为ANSI的方式,对于中文部分会产生乱码

2.什么是UTF-8的BOM?

BOM的全称是Byte Order Mark,BOM是微软给UTF-8编码加上的,用于标识文件使用的是UTF-8编码,即在UTF-8编码的文件起始位置,加入三个字节“EE BB BF”。这是微软特有的,标准并不推荐包含BOM的方式。采用加BOM的UTF-8编码文件,对于一些只支持标准UTF-8编码的环境,可能导致问题。比如,在Go语言编程中,对于包含BOM的代码文件,会导致编译出错。详细可见我的这篇文章

参考资料