ASCII Unicode UTF-8 字符集 字符编码
- 基本概念
- 字符
- 字符集
- 字符编码
- 字符集和字符编码
- ASCII 字符集
- Unicode 字符集
- UTF-8
- 附录
基本概念
字符集为每个字符分配了一个唯一的编号,通过这个编号就能找到对应的字符。在编码过程中我们经常会使用字符,而使用字符的前提就是把字符放入内存中,而放入内存中的仅仅是字符的编号,而不是真正的字符实体。
这就引出一个问题,如何将这些字符编号存入内存中,还能让计算机通过这些编号找到对应的真实字符实体。
字符
字符(Character
),简单点说,就是在在计算机和电信技术中各种文字和符号的总称。一个字符可以是一个中文汉字、一个英文字母、一个阿拉伯数字、一个标点符号、一个图形符号或者控制符号等。
字符集
字符集(Character Set
),就是多个字符的集合。不同的字符集包含的字符数量是不一样的,包含的字符也不一样,对应的编码方式也不同。例如,GB2312
是中国国家标准的简体中文字符集(其中包含简化汉字6763个+一般符号+序号+数字+拉丁字母+日文假名+希腊字母+俄语字母+汉语拼音符号+汉语注音字母,共7445个字符),而 ASCII
字符集只包含了128个字符(其中主要字符是英文字母+拉丁字母和一些简单的控制字符)。
另外,还有其他常用的字符集,如 GBK
字符集、Unicode
字符集等。
字符编码
字符编码(Character Encoding
),是指一种映射规则,根据这个映射规则可以将某个字符映射成其他形式的数据以便在计算机中存储和传输。例如 ASCII
字符编码规定使用单字节中低7位比特去编码所有字符,在这个编码规则下字母 A
的编号是 65
(ASCII码),因此写入存储设备的二进制值是 01000001
。每种字符集都有自己的字符编码规则,常用的字符集编码规则还有 UTF-8
等。
字符集和字符编码
ASCII 字符集
上个世纪60年代,美国制定了一套字符编码规则,对英文字符和二进制位之间的关系做了统一规定,这套编码规则就是 ASCII
编码,一直沿用至今。
ASCII
编码一共规定了128个字符的编码规则,这128个字符形成的集合就叫做 ASCII
字符集。在 ASCII
编码中,每个字符占用一个字节的后面7位,最前面的一位规定为0。下图是 ASCII
字符集中字符和码值的对应关系:
英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。而且,欧洲小国家特别多,每个国家可能都有自己的语言体系,语言环境十分复杂,为了解决这个问题,这些欧洲国家使用了一套延伸的 ASCII
字符集,利用字节中闲置的最高位编入新的符号,称为 EASCII
(Extended ASCII
):在 EASCII
中表示的256个字符中,前128字符和 ASCII
编码表示的字符完全一样,后128个字符每个国家或地区都有自己的编码标准。例如:130(二进制为 10000010
)在法语编码中代表了 é
,在希伯来语编码中代表了字母 Gimel (ג)
,在俄语编码中又会代表另外一个字符。
根据这个规则,就形成了很多子标准:ISO-8859-1
、ISO-8859-2
等。这些子标准适用于欧洲不同的国家地区。
至于亚洲国家的文字和符号那就更多了,光汉字就多达10万左右,如果按照 ASCII
码单字节表示,即使用上了最高位也只能表示256种字符,肯定是不够的,所以必须使用多字节来表示一个字符,因此就出现了后面的 Unicode
字符集和 GB2312
等字符集。比如,GB2312
字符集,使用两个字节表示一个汉字,所有理论上最多可以表示 65536 个字符(2^16)。
Unicode 字符集
ASCII
码字符集总共才能容纳256个字符,对于全世界各国语言来说,很难全部包含在内,所有就出现了 Unicode
字符集。
Unicode
字符集是一个很大的字符集合,现在的规模可以容纳100多万个符号,每个符号的编码都不一样。
需要注意的是,Unicode
只是一个字符集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何编码如何存储。这就造成了两个问题:
- 如何才能区分
Unicode
和ASCII
?计算机如何知道三个字节表示一个字符而不是分别表示三个字符呢? - 已经知道英文只用一个字节表示就够了,如果统一采用
Unicode
规定,每个字符都要用三个字节来表示,那么每个英文字符前都必须有两个字节是0,这对应存储来说是极大的浪费。
因此就出现了 UTF
(Unicode Transformation Formats
)系列的编码规则。UTF编码规则具体规定了 Unicode
字符集中的字符是如何编码的。
总结:
Unicode
是一个很大的字符集,它只规定了这个字符集中每个字符对应的码值是多少,具体的编码规则是由 UTF 系列的编码规则实现的。
UTF-8
它是一种编码规则,互联网的普及,强烈要求出现一种统一的编码方式。UTF-8
就是在互联网上使用最广泛的一种 Unicode
的实现方式(其他方式还有 UTF-16
、UTF-32
,不过基本不用),这里的关系是:UTF-8
编码是 Unicode
的实现方式之一。
UTF-8
是一种针对 Unicode
的可变长度字符编码规则,又称万国码。UTF-8
用1-4个字节编码 Unicode
字符,根据不同的字符而变化字节长度(UTF-8
编码可以容纳 2^21 个字符,总共200多万个字符)。
UTF-8
的编码规则只有两条:
- 对于单字节的符号,字节的第一位设为0,后面7位为这个字符的
Unicode
码,因此对于英文字母来说,UTF-8
编码和ASCII
码是相同的。 - 对于
n
字节的字符(n > 1
),第一个字节的前n
位都设为1
,第n+1
位设为0
,后面字节的前两位一律设为10
,剩下的没有提及的二进制位,全部为这个字符的Unicode
码。
下表总结了这个编码规则,字母 x
表示可用编码的位:
UTF 字节数 | UTF编码方式 |
---|---|
一个字节 | 0xxxxxxx |
两个字节 | 110xxxxx 10xxxxxx |
三个字节 | 1110xxxx 10xxxxxx 10xxxxxx |
四个字节 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
下面以汉字 严
为例,演示如何实现 UTF-8
编码:
已知 严
的 Unicode
编号是 U+4E25
,换算成二进制是 1001110 00100101
(注意,这是它的 Unicode
值,至于以什么样的二进制值存储和计算机中进行传输是通过编码方式来的) ,根据上表可以得出,存储这个字需要三个字节(两个字节的编码方式,除去首位固定的 110
和 10
,剩下的位数不够存放 1001110 00100101
),即格式应该是 1110xxxx 10xxxxxx 10xxxxxx
,然后,从 严
的最后一个二进制位开始,依次从后往前填入格式中的 x
,多出的位补 0
,这样就得到了 严
的 UTF-8
编码值是 11100100 10111000 10100101
,换算成十六进制就是 E4B8A5
。
附录
如果你希望查看完整的 Unicode
字符集,以及各种编码方式,可以戳这里。