Unicode代码点与编码
参考:代码点(Code Point)和代码单元(Code Unit)
完整的Unicode表:Unicode表
Unicode 中得代码点指的是编号。Unicode中的每个字符都有自己的一个编号,这个就是代码点
Unicode 属于编码字符集(CCS);其为每个字符映射为一个唯一的数字编号;这个数字编号被称为对应字符的代码点。
中文 | Unicode编号-代码点 |
---|---|
你 | \0x 4f60(\u 4f60) |
好 | \0x 597d(\u597d) |
严 | \0x4e25(\u4e25) |
中文与Unicode互转工具 |
字符编码
到目前为止,Unicode只是为每一个字符提供唯一对应的数字编号。因此,如何存储在计算机中还是一个值得继续研究的问题。
为什么需要编码?
计算机只擅长处理数字,它无法理解每个字符。一个汉字“你”,需要转为一个数字,存在计算机中。当我们输入一个汉字时,输入法将汉字转化为对用的字符编码,存在计算机中。
计算机内部是二进制存储的,数字只有0和1;最简单的一个数字0
或1
称为一个比特(bit)。比特之上还一个一些单位,包括字节(Byte,8位比特,8个0
或1
组成的数字组)。字节可能是一个更常用的读取单位。
编码模型(按照编码方式分类)
- 定长编码(Fixed-Length)
每个符号占用相同字节数。
- 优点:解码简单、随机访问高效。
- 缺点:空间利用率低(如UTF-32)。
- 典型应用:ASCII、UTF-32。
- 变长编码(Variable-Length)
不同符号占用不同字节数。
- 优点:节省空间。
- 缺点:解码需前缀匹配,复杂度高。
- 典型应用:UTF-8。
到目前为止,我们应该理解几点:
- Unicode将每个字符唯一地映射为一个数字。
- 对于一个字符集,每个字符唯一对应的数字编号,称为代码点。
- 计算机只擅长处理数字,因此,我们将字符集映射为数字。
- 尽管我们可以确定一个字符集的数字映射关系,但是还需要解决,如何实际存储在计算机中。这个问题由编码模型来解决。
- 编码模型按照编码方式分为定长编码和变长编码。
ASCII码
ASCII编码是一种定长编码方式。# ASCII码对照表
ASCII 一共定义了 128 个字符,使用了一个字节的 7 位。定义的这些字符包括英文字母 A-Z,a-z,数字 0-9,一些标点符号和控制符号。
例如A-> 0100 0001
,十六进制表示为\0x41
;对于英语系国家而言,ASCII码使用起来看来十分的足够。
Unicode码
ASCII码只含有英文字母和一些标点符号、控制字符。对于其他国家而言,无法使用。
Unicode码把各种字符都包含进来,构成一个字符集并分配一个数字编号。
计算机编码
要如何在计算机中存储Unicode码是一个值得研究的问题。
可以使用定长编码吗? 可以
应该使用定长编码吗? 定长编码可以使用,但是存在很大冗余;Unicode字符集中包含多种字符,使用32位比特(UTF-32),四字节数字或许可以实现定长编码,并兼容ASCII码。但是对于字母A
而言,对应的计算机编码为00000000 00000000 00000000 01100001
,是一个非常长的内容,并且前面3字节都存储为0,没有实际含义。对于一个文件而言,可能会产生大量的冗余。
因此,后面提出UTF-8,UTF-16;UTF-8使用1字节(8比特)作为最小的编码单位;这就是代码单元的概念。
代码单元(Code Unit):是指一个已编码的文本中具有最短的比特组合的单元。
UTF-8编码
Unicode 符号范围 | UTF-8 编码
(十六进制) | (二进制)
--------------------+----------------------
0000 0000-0000 007F | 0xxx xxxx
0000 0080-0000 07FF | 110x xxxx 10xx xxxx
0000 0800-0000 FFFF | 1110 xxxx 10xx xxxx 10xx xxxx
0001 0000-0010 FFFF | 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx
如何理解这种编码?
从0000 0000
到0000 007F
一共包含127个数字编号,因此,只需要7bit即可表示,对应的UTF-8编码就为0xxx xxxx
,其中x
表示可用的比特,这一段设计完全兼容ASCII。
从0000 0080
到0000 07FF
一共包含1920个数字编号,这就需要10bit进行编码;因此,UTF-8设计为110x xxxx 10xx xxxx
,其中x
共有10位,可以表示1920个数字编号。
依次类推…
在Unicode字符集中,每一个数字编号对应一个字符。因此采用UTF-8编码的时候,有些字符是1字节表示的,有些字符是两字节表示的,有些字符则需要3或4个字节。
编码过程实例:
汉字的范围在0000 0800 - 0000 FFFF
你-> \0x 4f60 转为2进制 0100 1111 0110 0000 填充: 1110 0100 1011 1101 1010 0000 转为16进制表示 \0xE4 \0xBD \0xA0
好-> \0x 597d 转为2进制 0101 1001 0111 1101 填充: 1110 0101 1010 0101 1011 1101 转为16进制表示 \0xE5 \0xA5 \0xBD
严-> \0x 4e25 转为2进制 0100 1110 0010 0101 填充: 1110 0100 1011 1000 1010 0101 转为16进制表示 \0xE4 \0xB8 \0xA5