Unicode和UTF-8

之前看过关于编码的知识,今天无意间看到编码又想不起编码是怎么一回事,于是搜搜资料做了一个总结,感谢网友的分享。

参考:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
http://cenalulu.github.io/linux/character-encoding/

字符集要正确编码转码一个字符需要三个关键元素:

  1. 字库表(character repertoire)
  2. 编码字符集(coded character set)
  3. 字符编码(character encoding form)

:字库表规定了所以可显示的字符,它决定了整个字符集能够展现表示的所有字符的范围

:编码字符集就是用一个编码值来表示一个字符在字库中的位置。

:字符编码就是编码字符集和实际存储数值之间的转换规则

ASCII字库规定了128个字符,所以它用一个字节就可以编码,而且实际存储的数值就是它的字符编码,
但在实际中128个字符远远不够像我们使用象形文字的国家,我们需要表示更多字符的字库。于是unicode
出现了,Unicode当然是一个很大的集合,现在的规模可以容纳100多万个符号。可以看到Unicode只是一个字库表,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。
UTF-8就是一种存储Unicode字符的方式。

UTF-8

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

如果一个字节的第一位是0,则这个字节单独就是一个字符;如果第一位是1,则连续有多少个1,就表示当前字符占用多少个字节

已知"严"的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(大小端模式)

学过计算机原理的都知道存储数据时按2种方式存放数据。例如4E25,需要两个字节存储,一个字节是4E,另一个字节是25,
4E在低地址,25在高地址,就是大端模式,25低地址,4E高地址,就是小端模式.

Unicode规范中定义,每一个文件的最前面分别加入一个表示编码顺序的字符,这个字符的名字叫做"零宽度非换行空格"(ZERO WIDTH NO-BREAK SPACE),用FEFF表示。这正好是两个字节,而且FF比FE大1。
如果一个文本文件的头两个字节是FE FF,就表示该文件采用大端方式;如果头两个字节是FF FE,就表示该文件采用小端方式。

你可能感兴趣的:(Unicode和UTF-8)