在计算机中,所有的数据在存储和运算时都要使用二进制数表示,例如,像 A、B、a、b等52个大小写字母以及0、1等数字还有一些常用的符号如 $、#、@ 等。
具体用哪些二进制数字表示哪个符号,每个人都可以约定自己的一套规则,这就叫编码规则。而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则,于是美国有关的标准化组织就制定了ASCII编码( ASCII 由 ANSI 制定),统一规定了上述常用符号用哪些二进制数来表示。
随着计算机的普及,在不同系统、国家和地区也出现了很多字符编码,比如 GB2312、BIG5, Shift JIS 等。对于同一个二进制数据,不同的编码会解析出不同的字符。于是 Unicode编码应运而生。 Unicode 为每种语言中的每个字符设定了统一并且唯一的二进制编码
Unicode,准确说为Unicode标准,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。该标准由 Unicode 联盟维护(该联盟于1991 年 1 月 3 日在加利福尼亚成立)。
Unicode 标准是基于Unicode 通用字符集( Unicode Universal Character Set)的标准来发展,该标准由国际标准 ISO/IEC 10646 定义的标准字符集。
Unicode 为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
Unicode 标准定义了一个代码空间,一组数值,范围从 0 到 10FFFF,称为 码点(code point),表示为U+0000 到 U+10FFFF,即表示编码范围为 0x0000 - 0x10FFFF,可定义一百多万个字符。
10 :0~16 共17平面
FFFF : 0~ 65535 共65536个字符(码点)
Unicode 代码空间分为 17 个平面,编号为 0 到 16,平面 0 是基本多语言平面 (BMP)。每个平面有2^16=65536个码位。Unicode计划使用了17个平面,一共有17*65536=1114112个码位
字符编码将字符映射为特定的字节规则,这些被某种规则定义的字符,统称为其的字符集。
Unicode 字符集可以通过不同的字符编码来实现,Unicode 标准定义了 Unicode Transformation Formats (UTF) 和 Universal Coded Character Set(UCS)
Unicode字符集常见的字符编码:
UTF 编码规则有 UTF-8、UTF-16、UTF-32
UCS 编码规则有 UCS-2(UTF-16)、UCS-4(UTF-32)
Unicode 字符集常见的编码规则为UTF,其字符编码规则有 UTF-8、UTF-16、UTF-32,分别以 8位(1字节)、16位(2字节)、32位(4字节) 作为编码单位,即需要 1~4 个字节来存储。
UTF-8 是一种变长字符编码,它可将字符编码为 1 至 4 个字节,具体取决于码点数值中有效二进制位的数量。UTF-8是我们最常见和常用的编码规则。
Unicode 编码范围(16进制) | UTF-8 编码方式(二进制) | 字节 |
---|---|---|
00 0000 – 00 007F | 0xxxxxxx (ASCII码) | 1 |
00 0080 – 00 07FF | 110xxxxx 10xxxxxx | 2 |
00 0800 – 00 FFFF | 1110xxxx 10xxxxxx 10xxxxxx | 3 |
01 0000 - 10 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx4 | 4 |
UTF-16 也是一种变长字符编码, 它可将字符编码成 2 字节或者 4 字节。
Unicode 编码范围(16进制) | 0000 0000 - 0000 FFFF |
---|---|
具体Unicode码(二进制) | xxxxxxxx xxxxxxxx |
UTF-16编码方式(二进制) | xxxxxxxx xxxxxxxx |
字节 | 2 |
Unicode 编码范围(16进制) | 0001 0000 - 0010 FFFF |
---|---|
具体Unicode码(二进制) | yy yyyyyyyy xx xxxxxxxx |
UTF-16编码方式(二进制) | 110110yy yyyyyyyy 110111xx xxxxxxxx |
字节 | 4 |
UTF-32 是固定长度的编码,始终占用 4 个字节,可容纳所有的 Unicode 字符。因此,只需直接存储 Unicode 码即可,不需要进行编码转换。
UTF-32缺点:
UTF-32优点:
规则简单, Unicode 不需转换;
位置固定,处理方便,查询效率高;
可存储更多符号;
最大程度兼容其他 Unicode 编码规则的字符;
Unicode 字节顺序标记( byte order mark ,BOM ) 是一个 Unicode 字符,它的作用是确定 Unicode 文件或流的字节顺序。
最小编码单元是多字节才会有字节顺序问题。UTF-8 的最小编码单元是一字节,所以 它是没有字节顺序问题。UTF-16 的最小编码单元是 2 个字节,在解析一个 UTF-16 字符之前,需要知道每个编码单元的字节顺序。
字符“A”的 Unicode 编码为 0041,字符“䄀(huò)”的 Unicode 编码为 4100,当计算机收到UTF-16 字节流 0041 时,系统是如何识别的呢?
在 UTF-16中,可以将 BOM ( U+FEFF) 作为文件或字符流的第一个字符放置,以指示文件或流的所有 16 位代码单元的字节顺序。
因此,对于多字节的编码单元,需要有一个标记( U+FEFF)显式的告诉计算机,按照什么样的顺序解析字符,也就是字节顺序。字节顺序分为 Big Endian 和 Little Endian。
当计算机收到 UTF 字节流 0041 时:
Big Endian :BOM 为 FEFF / 0000FEFF,文件的字节顺序标记为 0041
Little Endian :BOM 为 FFFE / FFFE0000,文件的字节顺序标记为 4100
编码 | 文件头 |
---|---|
UTF-8 | EF BB BF 41 |
UTF-16BE | FE FF 00 41 |
UTF-16LE | FF FE 41 00 |
UTF-32BE | 00 00 FE FF 00 00 00 41 |
UTF-32LE | FF FE 00 00 41 00 00 00 |
437—最初的IBM PC代码页,实现了扩展ASCII字符集
737—希腊语
850—“多语言(Latin-1)”(西欧语言)
852—“斯拉夫(Latin-2)”(中欧及东欧语言)
855—西里尔(Cyril)字母
857—土耳其语
858—带欧元符号的“多语言”
860—葡萄牙语
861—冰岛语
863—法语加拿大英语
865—北欧
866—西里尔(Cyril)字母
869—希腊语
874—泰文字母 (扩展了ISO 8859-11 )
1250—东欧拉丁字母 (与ISO-8859-2类似)
1251—古斯拉夫语 (与ISO-8859-5和KOI-8不兼容)
1252—西欧拉丁字母ISO-8859-1 (ISO-8859-1的超集)
1253—希腊语 (与ISO 8859-7类似)
1254—土耳其语 (ISO 8859-9的超集)
1255—希伯来语 (几乎是ISO 8859-8的超集)
1256—阿拉伯语 (与ISO 8859-6不兼容)
1257—波罗的海 (不是ISO 8859-4;后来的ISO 8859-13密切相关)
1258—越南语
1254—土耳其语
GB2312 或 GB 2312-80 是中国国家标准简体中文字符集,全称《信息交换用汉字编码字符集·基本集》,又称 GB 0,由中国国家标准总局发布,1981 年 5 月 1 日实施。GB 2312 编码通行于中国大陆。GB 2312 的编码范围为 2121H-777EH,与 ASCII 有重叠,通行方法是将 GB 码两个字节的最高位置 1 以示区别。
GBK 即汉字内码扩展规范,K 为汉语拼音 Kuo Zhan(扩展)中“扩”字的声母。GBK 向下与 GB2312 完全兼容,向上支持 ISO 10646 国际标准。GBK 包含GB2312 中的全部汉字、非汉字符号、 BIG5 中的全部汉字 等。GBK 采用双字节表示,总体编码范围为 8140-FEFE 之间。
GB18030,全称国家标准 GB 18030-2005《信息技术中文编码字符集》,最新的内码字集,是 GB 18030-2000的修订版。GB 18030 与 GB 2312-1980 和 GBK 兼容。采用一二四字节变长编码,最多可定义 161 万个字符。