为什么 utf8没有字节序,utf16、utf32有字节序
  gxJ4jYVTC9IN 2023年11月02日 93 0


关于这个问题困惑了很长时间,主要原因是在理解“字节序”时,将“解码”也考虑进来了,在这里将解码也一并解答。

 

第一,编码单元与编码单元在网络中传输的顺序是确定的。即使是多字节编码方案,在网络层传输是没有问题的。比如 a b c,分别代表三个字节,发送时顺序是abc,那么接收时,仍然是abc,这个顺序不会错乱。我们经常会想utf8是多字节编码,怎么就不会存在字节序问题,这一条就很好的解答这个问题了。

 

第二,字节序指的是编码单元内部的字节顺序。

1、因为utf8是变长编码,而且是单字节为编码单元,不存在谁在高位、谁在低位的问题,所以不存在顺序问题!顺便说一下解码,由于utf8的首字节记录了总字节数(比如3个),所以读取首字节后,再读取后续字节(2个),然后进行解码,得到完整的字节数,从而保证解码也是正确的。

2、utf16是变长编码,使用1个16-bit编码单元或者2个16-bit编码单元,utf32是定长编码,这里拿utf16举例,在基本平面总是以2个字节为编码单元,鉴于“第一条”编码单元与编码单元之间的顺序是正确的,问题只能在编码单元内部中字节与字节的顺序,由于硬件cpu的不同,编码单元内部字节与字节的顺序不确定。假如cpu是大端序那么高位在前,如果cpu是小端序那么低位在前,为了区分,所以有了BOM(byte order mark),然后计算机才能知道谁是高位,谁是低位,知道了高低位,从而能正确组装,然后才能解码正确。

例如,一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?如果BOM是大端序,那么代码点就应该是594E,那么就是“奎”,如果BOM是小端序,那么代码点就应该是4E59,就是“乙”了。

 

综上所述,因为utf8是单字节为编码单元,在网络传输时,不存在字节序列问题。在解码时,由于首字节记录了总字节数,所以能正确解码。

因为utf16是定长编码,总是以2个字节为编码单元,在网络传输时,不存在字节序列问题。在解码时,由于cpu硬件差异,存在字节序问题,所以通过BOM来标记字节顺序;

 

理解了上述原理也就明白了为什么会有utf8、utf8-无BOM、utf16-big endian、utf16-little endian这几种保存格式了。

 

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  ehrZuhofWJiC   2024年04月26日   42   0   0 日志Java
gxJ4jYVTC9IN