字符编码的总结
学习编程的时候经常会遇到字符编码的问题,花了一天的时间对字符编码进行了比较系统的了解,下面的内容是我参考别的资料,结合一些自己的理解汇总而成的,不一定准确,用作总结。
字符
字符包括英文字母,汉字,日文,阿拉伯文,包括标点符号等,字符不是计算机概念,纸上写的也叫。
字符集
字符集就是字符的集合,一大堆同类的字符放在一起。
字符编码
字符编码就是在计算机中给字符编一个编码,和字符本身有对应关系。
字体
字体可以理解成同一个字符的不同展示方式,读取一个字符后,结合对应的字体文件显示出这个字符的字体效果,更换字体设定,同一个字符会有不同的显示效果。
ASCII码
ASCII码是最早的字符编码,只考虑了英文环境,没有考虑其他文字,所以只有8bit,编码存储能力极其有限。之所以不多用几位,主要是因为当时存储水平不允许,能省则省。
问题是世界上不是只有英文啊,其他字符怎么办?
GB2312
因为ASCII码极其有限的编码能力要应对天朝N多个字的问题,开发了GB2312码,台湾对应的BIG5,日本也有自己的,特点就是使用双字节16bit来存储。
GBK
因为GB2312存储还是有限,一些字符还是没法编码,这也就是为什么很多人去办身份证的时候,警察告诉你你们的地区的名字的字打不出来的原因。
为了解决这个问题,对GB2312进行了扩展,结果就是GBK
GB18030
还不够呢,继续拓展 GB18030,不过一般用不到
乱码
问题又来了,互联网发展起来了,世界交互大大加强了,用GB码编写的文件和网页在非GB码的国家地区显示就是乱码,如果一个文件或者页面里面用到多个国家的编码,显示出来就是乱码。
Unicode
于是就有人想到要弄一个足够大的编码系统,把全世界所有的字符都能够编进去,这就是Unicode。
通用的字符集叫做UCS(UNiversal Character Set),有UCS-2,UCS-4,UCS-2和UCS-4只规定了代码点和文字之间的对应关系,并没有规定代码点在计算机中如何存储。
对应存储的字符编码叫做Unicode,但是这又带来一个问题,如果选择很大的编码,那么意味着对于英文字母这些编码很小的字符,会浪费很大的空间,如果选择小了,可能后面又不够用,悲剧重演。为了两不误,人们想到了变长的编码,就是再对Unicode编码进行一次转换,转换的结果就是UTF(UniCode Transformation Format)。
UTF-8
目前Unicode使用的两个字节的UCS-2方案,UTF有好几种,UTF-8,UTF-16,UTF-32,现在最常用的是UTF-8,它是一种变长的编码。
BOM问题
BOM byte-order mark字节顺序标记,插入到编码文件头部的特殊标记,
用来标记多字节编码文件的编码类型和字节顺序(big-endian或little- endian)。
这里不同平台上因为历史原因有一些混乱问题,具体如下,了解一下。
来自知乎梁海的介绍
UTF-8 不需要 BOM,尽管 Unicode 标准允许在 UTF-8 中使用 BOM。所以不含 BOM 的 UTF-8 才是标准形式,在 UTF-8 文件中放置 BOM 主要是微软的习惯(顺便提一下:把带有 BOM 的小端序 UTF-16 称作「Unicode」而又不详细说明,这也是微软的习惯)。BOM(byte order mark)是为 UTF-16 和 UTF-32 准备的,用于标记字节序(byte order)。微软在 UTF-8 中使用 BOM 是因为这样可以把 UTF-8 和 ASCII 等编码明确区分开,但这样的文件在 Windows 之外的操作系统里会带来问题。「UTF-8」和「带 BOM 的 UTF-8」的区别就是有没有 BOM。即文件开头有没有 U+FEFF。UTF-8 的网页代码不应使用 BOM,否则常常会出错。
需要注意编码问题的地方
- 文件的读写
- 网页的设计
- 网络编程
- 数据库
- 开发的源文件编码
参考资料
- 常见编码和编码头BOM https://www.cnblogs.com/signheart/p/c3b1000186199e89d4e02c33f39ed418.html
- 字符编码笔记:ASCII,Unicode 和 UTF-8 http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
- 字符集和字符编码(Charset & Encoding) https://www.cnblogs.com/skynet/archive/2011/05/03/2035105.html