Unicode 概念
Note
Unicode 是国际标准字符集,它将世界各种语言的每个字符定义一个唯一的编码,以满足跨语言、跨平台的文本信息转换。
现在的规模可以容纳 100 多万个符号,位置靠前的字符用一个字节就能存储,位置靠后的字符用三个字节才能存储。
它从 0 开始,为每个符号指定一个编号,这叫做 “码点”(code point),比如码点
0(U+0000)
的符号就是null
,码点24179(U+5e73)
的符号就是平
。U+ 表示紧跟在后面的十六进制数是Unicode 的码点。例如
U+0000
表示null
,U+0639
表示阿拉伯字母Ain
,U+0041
表示英语的大写字母A
,U+4E25
表示汉字严
。具体的符号对应表,可以查询 unicode.org,或者专门的 汉字对应表。或者直接 在线查看完整的 Unicode 字符集
这里比较重要的概念是码点,
为了在计算机中处理字符集,必须把字符集数字化,就是给字符集中的每一个字符一个编号,计算机程序中要用字符,直接用这个编号就可以了。于是就出现了编码后的字符集,叫做编码字符集 (Coded Code Set)。编码字符集中每一个字符都和一个编号对应。那么这个编号就是代码点(Code Point)。
所以码点就是对应字符集的一个编号。
对于 Unicode 来讲,码点就是 【十六进制数】,比如 U+0041, 0041 = 4*16+1*1=65
Unicode 诞生背景
- ASCII 编码,最多可以表示 256 个符号(单字节=8bit)。英语用 128 个符号编码就够了,但是用来表示其他语言,128 个符号是不够的。
- 对于有些国家需要使用的符号就更多,汉字就多达 10 万左右。一个字节只能表示 256 种符号,肯定是不够的,就必须使用多个字节表达一个符号。比如,简体中文常见的编码方式是 GB2312,使用
两个字节
表示一个汉字,所以理论上最多可以表示 256 x 256 = 65536 个符号。- ASCII 码,由于不同国家存在着不同编码方式,同一个二进制数字可以被解释成不同的符号 (ASCII 码 128–255 符号)。如果用错误的编码方式解读文本文件,就会出现乱码。
Unicode 实现方式
UTF 是 Unicode Transformation Format 的缩写,意思是“Unicode 转换格式”,后面的数字表明至少使用多少个比特位(Bit)来存储字符。
Unicode 可以使用的编码有三种,分别是:
- UTF-8:一种变长的编码方案,使用 1~4 个字节来存储;
- UTF-16:介于 UTF-8 和 UTF-32 之间,使用 2 个或者 4 个字节来存储,长度既固定又可变。
- UTF-32:一种固定长度的编码方案,不管字符编号大小,始终使用 4 个字节来存储;
UTF-8
UTF-8 的编码规则很简单:
- 如果只有 1 个字节,字节的第一位设为
0
,后面 7 位为这个符号的 Unicode 码,这和 ASCII 编码完全一样,因此 UTF-8 是兼容 ASCII 的; - 对于
n
字节的符号(n > 1
),第一个字节的前n
位都设为1
,第n + 1
位设为0
,后面字节的前两位一律设为10
。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
编号范围 (十六进制) | UTF-8 编码方式(二进制) | 字节 |
---|---|---|
0x0000 - 0x007F | 0xxxxxxx | 1 |
0x0080 - 0x07FF | 110xxxxx 10xxxxxx | 2 |
0x0800 - 0xFFFF | 1110xxxx 10xxxxxx 10xxxxxx | 3 |
0x010000 - 0x10FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx4 | 4 |
下面,还是以汉字 严
为例,演示如何实现 UTF-8 编码。
严
的 Unicode 是 4E25
(100111000100101
),根据上表,可以发现 4E25
处在第三行的范围内(0000 0800 - 0000 FFFF
),因此 严
的 UTF-8 编码需要三个字节,即格式是 1110xxxx 10xxxxxx 10xxxxxx
。然后,从 严
的最后一个二进制位开始,依次从后向前填入格式中的 x
,多出的位补 0
。这样就得到了,严
的 UTF-8 编码是 11100100 10111000 10100101
,转换成十六进制就是 E4B8A5
。
补充
一个 char 是 2 字节