字符编码那些事儿
Unicode,ASCII,UTF-8,GB2312......这些到底是什么?为什么vim打开编辑文档出现乱码?怎么修改字符编码之后就解决了?
很多与文档编辑有关的软件,也总是涉及到设置字符编码的选项?应该怎么设置?
让我们带着疑问一步一步拨云见日。
1、为什么要有字符编码?
计算机系统中所有信息以二进制形式存储,因此为了将我们日常所用的字符转化为计算机内部的信息,需要通过字符编码将这些字符转化为二进制码。那么这里涉及到两个概念:
字符集:字符集就是用十进制来表示各种字符的集合。
字符编码:将字符转化为二进制编码的规则。
2、为什么会有多种编码方式?
ASCII
最早,ASCII(American standard Code for information Interchange)作为美国人发明的字符编码方式,其字符集包括128个字符(0-127号),由8位二进制表示,其中最前面一位统一规定为0,后7位用来表示这些字符。比如‘A’在字符集中是65,表示为二进制是01000001。
但后来当世界各地都开始用计算机时他们的字母里很多是ASCII里面没有,因此将ASCII码中127号之后的空位来表示这些新字符,因此从128-255这一页字符集被称为扩展字符集。
GB2312
等到中国人使用计算机后,发现完全没有中文字符啊,怎么办?于是中国人提出的字符编码方案为GB2312,相当于对ASCII的扩展。小于等于127号的继续使用,并且用2个大于127的字节表示一个中文字符,前面的一个字节(他称之为高字节
)从0xA1用到 0xF7,后面一个字节(低字节
)从0xA1到0xFE,这样我们就可以组合出大约7000多个简体汉字了。在这些编码中,还把数学符号,罗马希腊的字母,日文的假名都编进去了,连ASCII里本来就有的数字,标点,字母都统统重新编了两个字节长的编码,这就是常说的“全角”字符,而原有的127号以下的那些字符称为“半角”。
GBK
但是中文还是不够用,很多冷门生僻字和繁体字等还是无法识别怎么办?于是要求高字节大于127的就认为是2字节的中文字符,这样结果脱战之后就是GBK标准。GBK相比GB2312,增加了近20000个新汉字与符号。但后来少数民族同胞也要用计算机,于是为了扩展少数民族字符,GBK被扩展为GB18030。这些编码标准统称为DBCS(Double Byte Character Set,双字节字符集)。
Unicode与UTF-8/UTF-16
为了方便全世界的文化交流,满足跨语言、跨平台文本转换、处理需求,ISO(国际标准化组织)决定制定一个统一的包括全世界所有字符的编码标准,包括字符集、编码方案等,他们打算叫他"Universal Multiple-Octet Coded Chracter Set",简称UCS,俗称Unicode。
在Unicode中,直接规定必须用两个字节,ASCII那些半角字符,保持原编码不变,只是将其长度由原来的8位扩展为16位(高8位全为0),而其他文化和语言的字符则全部重新统一编码。
问题是:(1)计算机怎么知道2个字节为一个字符,如何识别2个字节为一个字符?(2)半角字符如果用两个字节表示,很浪费空间,而计算机大部分内容还是英文。
而作为Unicode字符集的一种编码方式,UTF-8采用变长编码,使用1-4个字节表示一个字符,其特点是,对不同范围的字符使用不同长度的编码。
UTF-8的编码规则:
(1)单字节符号,字节的第一位设为0,后面7位为这个符号的Unicode码。因此对于英文字母,UTF-8编码和ASCII码是相同的。
(2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10,剩下的没有提及的二进制位,全为这个符号的unicode码。
类似的,UTF-16使用二字节或四字节表示一个字符的变长编码。
3、为什么会出现乱码?
编码方式不兼容会导致乱码,例如当一个文件采用编码A的方式编码,但按照编码B的方式解码,必然得到乱码。
参考资料:
(2)字符编码笔记:ASCII,Unicode 和 UTF-8