Unicode只是一个符号集,它只规定了符号的二进制代码
UTF-8是Unicode的一种实现方式(其它还有UTF-16,UTF-32等)。其最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8
的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于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
|
下面,还是以汉字
“
严
”
为例,演示如何实现
UTF-8
编码。已知
“
严
”
的
unicode
是
4E25
(
100111000100101
),根据上表,可以发现
4E25
处在第三行的范围内(
0000 0800-0000 FFFF
),因此
“
严
”
的
UTF-8
编码需要三个字节,即格式是
“1110xxxx
10xxxxxx 10xxxxxx”
。然后,从
“
严
”
的最后一个二进制位开始,依次从后向前填入格式中的
x
,多出的位补
0
。这样就得到了,
“
严
”
的
UTF-8
编码是
“11100100 10111000 10100101”
,转换成十六进制就是
E4B8A5
。
Little endian
和
Big endian
Unicode
码可以采用
UCS-2
格式直接存储。以汉字
”
严
“
为例,
Unicode
码是
4E25
,需要用两个字节存储,一个字节是
4E
,另一个字节是
25
。存储的时候,
4E
在前,
25
在后,就是
Big end
ian
方式;
25
在前,
4E
在后,就是
Little endian
方式。即
第一个字节在前,就是
”大头方式“(Big endian),第二个字节在前就是”小头方式“(Little endian)
。
Unicode
规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做
”
零宽度非换行空格
“
(
ZERO WIDTH NO-BREAK SPACE
),用
FEFF
表示。这正好是两个字节,而且
FF
比
FE
大
1
。如果一个文本文件的头两个字节是
FE FF
,就表示该文件采用大头方式;如果头两个字节是
FF FE
,就表示该文件采用小头方式。
那么对于“严”字不同的编码存储方式其表现为
1
)
ANSI
:文件的编码就是两个字节
“D1 CF”
,这正是
“
严
”
的
GB2312
编码,这也暗示
GB2312
是采用大头方式存储的。
2
)
Unicode
:编码是四个字节
“FF FE 25 4E”
,其中
“FF FE”
表明是小头方式存储,真正的编码是
4E25
。
3
)
Unicode big endian
:编码是四个字节
“FE FF 4E 25”
,其中
“FE FF”
表明是大头方式存储。
4
)
UTF-8
:编码是六个字节
“EF BB BF E4 B8 A5”
,前三个字节
“EF BB BF”
表示这是
UTF-8
编码,后三个
“E4B8A5”
就是
“
严
”
的具体编码,它的存储顺序与编码顺序是一致的.