共计 1885 个字符,预计需要花费 5 分钟才能阅读完成。
字符编码的问题看似很小,常常被技术人员漠视,然而很容易导致一些莫名其妙的问题。这里总结了一下字符编码的一些普及性的常识,心愿对大家有所帮忙。
ASCII 码
美国国家标准协会 ANSI 制订了一个规范,规定了罕用字符的汇合以及每个字符对应的编号,这就是 ASCII 字符集(Character Set),也称 ASCII 码。
过后的计算机广泛应用 8 比特字节作为最小的存储和处理单元,加之过后用到的字符也很少,26 个大小写英文字母还有数字再加上其余罕用符号,也不到 100 个,因而应用 7 个比特位 (2^7=128) 就能够高效的存储和解决 ASCII 码,剩下最高位 1 比特被用作一些通信零碎的奇偶校验。下图为 ASCII 码字符集:
图中,每个字符都有对应的数字,叫做码点。如 A 对应的码点为 65。
Unicode 字符集
Unicode 字符集涵盖了目前人类应用的所有字符,并为每个字符进行对立编号,调配惟一的字符码(Code Point)。Unicode 字符集将所有字符依照应用上的频繁度划分为 17 个层面(Plane),每个层面上有 216=65536 个字符码空间。
编码零碎的变动
在 Unicode 呈现之前,所有的字符集都是和具体编码方案绑定在一起的,这种形式的毛病在于,字符和字节流之间耦合得太严密了,从而限定了字符集的扩大能力。假如当前火星人入住地球了,要往现有字符集中退出火星文就变得很难甚至不可能了,而且很容易毁坏现有的编码规定。因而 Unicode 在设计上思考到了这一点,将字符集和字符编码方案分来到。
常见的 Unicode 编码
UTF-8
如图所示
- 如果一个字节的第一位为 0,那么代表以后字符为单字节字符,占用一个字节的空间。0 之后的所有局部(7 个 bit)代表在 Unicode 中的序号。
- 如果一个字节以 110 结尾,那么代表以后字符为双字节字符,占用 2 个字节的空间。110 之后的所有局部(5 个 bit)加上后一个字节的除 10 外的局部(6 个 bit)代表在 Unicode 中的序号。且第二个字节以 10 结尾
- 如果一个字节以 1110 结尾,那么代表以后字符为三字节字符,占用 3 个字节的空间。110 之后的所有局部(5 个 bit)加上后两个字节的除 10 外的局部(12 个 bit)代表在 Unicode 中的序号。且第二、第三个字节以 10 结尾
- 如果一个字节以 10 结尾,那么代表以后字节为多字节字符的第二个字节。10 之后的所有局部(6 个 bit)和之前的局部一起组成在 Unicode 中的序号。
utf- 8 的益处是
- 反对 ascii:一个 utf- 8 遍码的英文文本用 ascii 读取没有任何问题
- 节约空间:utf- 8 让 unicode 里码点小的字符也相应领有更短的长度
UCS-2/UTF-16
如果要咱们来实现 Unicode 字符集中 BMP 字符的编码方案,咱们会怎么实现?因为 BMP 层面上有 216=65536 个字符码,因而咱们只须要两个字节就能够齐全示意这所有的字符了。
举个例子,“中”的 Unicode 字符码是 0x4E2D(01001110 00101101),那么咱们能够编码为 01001110 00101101(大端)或者 00101101 01001110(小端)。
UCS- 2 和 UTF-16 对于 BMP 层面的字符均是应用 2 个字节来示意,并且编码失去的后果完全一致。不同之处在于,UCS- 2 最后设计的时候只思考到 BMP 字符,因而应用固定 2 个字节长度,也就是说,他无奈示意 Unicode 其余层面上的字符,而 UTF-16 为了解除这个限度,反对 Unicode 全字符集的编解码,采纳了变长编码,起码应用 2 个字节,如果要编码 BMP 以外的字符,则须要 4 个字节结对,这里就不探讨那么远,有趣味能够参考维基百科。
Windows 从 NT 时代开始就采纳了 UTF-16 编码,很多风行的编程平台,例如.Net,Java,Qt 还有 Mac 下的 Cocoa 等都是应用 UTF-16 作为根底的字符编码。例如代码中的字符串,在内存中相应的字节流就是用 UTF-16 编码过的。
锟斤拷
锟斤拷是常见的中文乱码,常见到了有了知名度
unicde 字符集有一个非凡的替换符号,专门用于展现无奈辨认或展现的字符,如图所示:
有些编辑器在编码为 utf- 8 时会把无奈辨认或者展现的字符主动替换为这个替换符号,用于提醒用户。
而如果用户点击了保留,它在 utf- 8 编码后则是 3 字节长度的二进制数字。
2 个问号字符连在一起,把文件再用 GBK 编码读取,关上后就会看到以前是 2 个替换符号的中央当初都变成了锟斤拷。
参考
- 对于字符编码,你所须要晓得
- 你懂乱码吗?锟斤拷烫烫烫(详解 ASCII、Unicode、UTF-32、UTF- 8 编码)
- [十分钟搞清字符集和字符编码](