字符集
首先必须知道一个概念 - 字符集
计算机中的所有字符, 说到底都是用二进制的 0/1 排列组合来表示的, 因此就需要有一个规范来规定每个字符对应 0/1 排列组合, 这样的规范就是字符集.
Unicode, ASCII, GB2312, GBK 都是字符集. UTF-8不是!
ASCII
最早的计算机在设计时采用 8 个 bit 作为一个字节 - byte, 所以, 一个字节能表示的范围就是 00000000 到 11111111, 也就是 0 到 255, 一共 256 种状态, 每一个状态对应一个符号, 可以表示 256 个符号.
美国有关的标准化组织就出台了 ASCII 编码, 对英语字符, 数字以及部分符号与二进制位之间的关系, 做了统一规定, 一共规定了 128 个字符的编码. 只占用了一个字节的后面 7 位, 最前面一位统一规定为 0, 一直沿用至今.
每个 ASCII 编码占用一个字节, 即 8 bit.
如果加上最前面一位, 即后 128 个最前面一位为 1 的编码, 被称为扩展ASCII码. 显示英语用 前 128 个符号编码就够了, 但是用来表示其他语言是不够的. 比如, 在法语中, 字母上方有注音符号, 它就无法用 ASCII 码表示. 于是, 一些欧洲国家就利用字节中闲置的最高位编入新的符号. 比如, 法语中的 é 的编码为 130(二进制10000010). 这样一来, 这些欧洲国家使用的编码体系, 可以表示最多 256 个符号.
但是中文怎么办?
GBK与GB2312
如果要表示中文, 显然一个字节是不够的, 至少需要两个字节, 而且还不能和 ASCII 编码冲突, 所以, 中国制定了 GB2312 编码, 用来把中文编进去.
后来发现这 GB2312 还是不够用, 汉字实在是太多了, 于是国内程序员又对这个字符集进行了扩充, 总之最后扩充成了GBK标准, GBK 依旧使用两个字节表示一个汉字. GBK 是在 GB2312 基础上扩容后兼容 GB2312 的标准.
同理, 日文和韩文等其他语言也有这个问题. 为了统一所有文字的编码, Unicode 应运而生.
Unicode
它为每种语言中的每个字符设定了统一并且唯一的二进制编码, 能够使计算机实现跨语言、跨平台的文本转换及处理.
Unicode 与 ASCII 是兼容的, 通常用两个字节表示一个字符, 原有的英文编码从单字节变成双字节,只需要把高字节全部填为 0 就可以.
但是, 这里就有一个问题, 这些英文字母只需要一个字节就能存储, 现在用两个字节, 文件的体积就可能要扩大两倍. 这没办法接受!
因此,Unicode 有了各种各样的实现形式,最出名的是UTF-8
UTF-8
UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式.
UTF-8 最大的一个特点, 就是它是一种变长的编码方式. 它可以使用1~4个字节表示一个符号, 根据不同的符号而变化字节长度.
UTF-8 的编码规则:
- 对于单字节的符号, 字节的第一位设为0, 后面7位为这个符号的 Unicode 码. 因此对于英语字母, UTF-8 编码和 ASCII 码是相同的.
- 对于 n 字节的符号(n > 1), 第一个字节的前 n 位都设为1, 第 n + 1 位设为 0, 后面字节的前两位一律设为 10. 剩下的没有提及的二进制位, 全部为这个符号的 Unicode 码.
举例:
Unicode符号范围(十六进制) | UTF-8编码方式(二进制) |
---|---|
0000 0000-0000 007F | 0xxxxxxx |
0000 0080-0000 07FF | 110xxxxx 10xxxxxx |
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx |
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
总结
- Unicode, ASCII, GB2312, GBK 都是字符集. UTF-8不是.
- Unicode 只规定了符号的二进制代码, 并没有规定这个二进制代码应该如何进行存储. UTF-8 是则是 Unicode 储存的实现方式之一.
- GB2312 是为了解决 ASCII 不支持中文的问题.
- GBK 是在 GB2312 基础上扩容后兼容 GB2312 的标准.
参考
- Unicode 百度百科
- 字符编码笔记:ASCII,Unicode 和 UTF-8