为什么UTF-8没有字节序问题?

作者: 果壳网川岛

关于编码的问题困扰了我好久,每次遇到都完全解决不了我的疑惑,这次彻底的看了几篇文章总算是看懂了,这里分享给大家。

一、UTF-8编码怎么编

UTF-8编码是Unicode字符集的一种编码方式,其特点是使用变长字节数来存储数据。一般是1到4个byte,当然,也可以更长,实际上4个byte可以表示2的32次方个不同字符,即4294967296个(约43亿),已经足以编码人类现使用的绝大部分字符了。

为什么要变长呢?你可以理解为按需分配,比如一个字节足以容纳所有的ASCII码字符,那何必补一堆0用更多的字节来存储呢?实际上变长编码有其优势也有其劣势,优势是节省空间、自动纠错性能好、利于传输、扩展性强,劣势是不利于程序内部处理,比如正则表达式检索,UTF-16、UTF-32这些等宽字符编码就比较适合程序处理,但是又比较耗存储空间。那UTF-8编码实现是怎样的呢?

我们已经知道UTF-8编码至少有一个字节,从首字节就可以判断一个字符的UTF-8编码有几个字节。如果首字节以0开头,肯定是单字节编码,如果以110开头,肯定是双字节编码,如果是1110开头,肯定是三字节编码,以此类推。除了单字节外,多字节UTF-8码的后续字节均以10开头。

所以1~4字节UTF-8编码看起来是这样的:

0xxxxxxx
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

单字节可编码的Unicode范围:\u0000~\u007F(0~127)
双字节可编码的Unicode范围:\u0080~\u07FF(128~2047)
三字节可编码的Unicode范围:\u0800~\uFFFF(2048~65535)
四字节可编码的Unicode范围:\u10000~\u1FFFFF(65536~2097151)

127、2047、66535、2097151这几个临界值怎么来的?因为UTF-8编码含有用于标识编码的0、110、1110等,所以1~4个字节的UTF-8编码有效位数分别为7、11、16、21。

二、什么是字节序

如果一个数据大于127(2的8次方减1),就必须有两个字节或多个字节来放了。一个数字肯定是有高位和低位的,这个小学就有讲过,比如十进制数13,1就是高位,3就是低位。于是问题就出现了,计算机进行数据存取是先处理高位,再处理低位呢,还是处理低位,再处理高位?这个问题就好比吃鸡蛋因该从尖的一头剥开还是应该从圆的一头剥?不同的硬件架构可能使用不同的字节序。先处理高位再处理低位,叫做大端字节序;先处理低位再处理高位,叫做小端字节序。

三、回到题目

提一下UTF-16,UTF-16是用定长2个字节来编码Unicode字符,其编码单位是两个字节,因此需要考虑字节序问题,因为2个字节哪个存高位哪个存低位需要确定。而UTF-8的编码单元是1个字节,所以就不用考虑字节序问题。

关于大端和小端的问题,这里有篇很好的文档

http://betterexplained.com/articles/understanding-big-and-little-endian-byte-order/

猜你喜欢

转载自blog.csdn.net/qq_32252957/article/details/83054152