欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

UTF-8学习笔记贴

程序员文章站 2022-03-31 11:30:55
...

UTF-8 学习笔记(C++)

学习原因

虽然从事多年编程,之前一直在国外项目,近一年接收国内项目,对中文的支持成为必要的需求,之前遇到乱码的问题,都是网上找解决方案,没有从根本上理解这个事情,抽出时间理解一下相关底层的处理逻辑,相关知识点在此处记录。

什么是 UTF-8

摘录自百度百科:https://baike.baidu.com/item/UTF-8/481798?fromtitle=UTF8&fromid=772139&fr=aladdin


UTF-8(8 位元,Universal Character Set/Unicode Transformation Format)是针对 Unicode 的一种可变长度字符编码。它可以用来表示 Unicode 标准中的任何字符,而且其编码中的第一个字节仍与 ASCII 相容,使得原来处理 ASCII 字符的软件无须或只进行少部份修改后,便可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。


摘要自*:https://zh.wikipedia.org/wiki/UTF-8


UTF-8(8-bit Unicode Transformation Format)是一种针对 Unicode 的可变长度字符编码,也是一种前缀码。它可以用一至四个字节对 Unicode 字符集中的所有有效编码点进行编码,属于 Unicode 标准的一部分,最初由肯·汤普逊和罗布·派克提出。由于较小值的编码点一般使用频率较高,直接使用 Unicode 编码效率低下,大量浪费内存空间。UTF-8 就是为了解决向后兼容 ASCII 码而设计,Unicode 中前 128 个字符,使用与 ASCII 码相同的二进制值的单个字节进行编码,而且字面与 ASCII 码的字面一一对应,这使得原来处理 ASCII 字符的软件无须或只须做少部分修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或发送文字优先采用的编码方式。


划重点:

  • 第一个字节 ASCII 相容
  • 处理 ASCII 字符的软件无须或只进行少部份修改后,便可继续使用

引出问题:

  • 第一个字节兼容,那么后面的字节怎么处理
  • ASCII 字符串软件如何修改可以继续使用(可能和上个问题是同一个问题)

UTF-8 占几个字节

摘录自百度百科:https://baike.baidu.com/item/UTF-8/481798?fromtitle=UTF8&fromid=772139&fr=aladdin

UCS 字符 U+0000 到 U+007F(ASCII)被编码为字节 0×00 到 0x7F(ASCIⅡ 兼容)。这意味着只包含 7 位 ASCIl 字符的文件在 ASCIⅡ 和 UTF-8 两种编码方式下是一样的。
所有大于 0x007F 的 UCS 字符被编码为一个有多个字节的串,每个字节都有标记位集。因此,ASCIl 字节(0x00-0x7F)不可能作为任何其他字符的一部分。表示非 ASCIl 字符的多字节串的第一个字节总是在 0xC0 到 0XFD 的范围里,并指出这个字符包含多少个字节。多字节串的其余字节都在 0x80 到 0xBF 范围里。这使得重新同步非常容易,并使编码无国界,且很少受丢失字节的影响。
UTF-8 编码字符理论上可以最多到 6 个字节长,然而 16 位 BMP 字符最多只用到 3 字节长,Bigendian UCS-4 字节串的排列顺序是预定的,字节 0xFE 和 OxFF 在 UTF-8 编码中从未用到


摘要自*:https://zh.wikipedia.org/wiki/UTF-8

UTF-8 使用一至六个字节为每个字符编码(尽管如此,2003 年 11 月 UTF-8 被 RFC 3629 重新规范,只能使用原来 Unicode 定义的区域,U+0000 到 U+10FFFF,也就是说最多四个字节):

128 个 US-ASCII 字符只需一个字节编码(Unicode 范围由 U+0000 至 U+007F)。
带有附加符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则需要两个字节编码(Unicode 范围由 U+0080 至 U+07FF)。
其他基本多文种平面(BMP)中的字符(这包含了大部分常用字,如大部分的汉字)使用三个字节编码(Unicode 范围由 U+0800 至 U+FFFF)。
其他极少使用的 Unicode 辅助平面的字符使用四至六字节编码(Unicode 范围由 U+10000 至 U+1FFFFF 使用四字节,Unicode 范围由 U+200000 至 U+3FFFFFF 使用五字节,Unicode 范围由 U+4000000 至 U+7FFFFFFF 使用六字节)。
对上述提及的第四种字符而言,UTF-8 使用四至六个字节来编码似乎太耗费资源了。但 UTF-8 对所有常用的字符都可以用三个字节表示,而且它的另一种选择,UTF-16 编码,对前述的第四种字符同样需要四个字节来编码,所以要决定 UTF-8 或 UTF-16 哪种编码比较有效率,还要视所使用的字符的分布范围而定。不过,如果使用一些传统的压缩系统,比如 DEFLATE,则这些不同编码系统间的的差异就变得微不足道了。若顾及传统压缩算法在压缩较短文字上的效果不大,可以考虑使用 Unicode 标准压缩格式(SCSU)。


划重点:

  • 第一个字节中 [ 0x00 - 0x7F ] (ASCII 兼容)最高位
  • 第一个字节标记了整个数的字节数,
0b0zzzzzzz 表示由1个字节组成的字符,剩余7位用户表示字符值(即单字节ASCII码)
0b110yyyyy 表示由2个字节组成的字符,剩余6位用户表示字符值
0b1110xxxx 表示由3个字节组成的字符,剩余5位用户表示字符值
0b11110www 表示由4个字节组成的字符,剩余4位用户表示字符值
首字节 首字节值区间 字节数
0b0zzzzzzz 0x00~0x7F < 0x8F 1
0b110yyyyy 0x8F~0xDF < 0xE0 2
0b1110xxxx 0xE0~0xEF < 0xF0 3
0b11110www 0xF0~0xF7 < 0xF8 4

UTF-8 字符值

字节数 字节 1 字节 2 字节 3 字节 4 有效字符值位数 字符值 字符值区间
1 0b0zzzzzzz - - - 7 = 7 0bzzzzzzz 0x00~0x7F < 0x8F
2 0b110yyyyy 0b10zzzzzz - - 5 + 6 = 11 0byyyyyzzzzzz 0x8F~0x7FF < 0x800
3 0b1110xxxx 0b10yyyyyy 0b10zzzzzz - 4 + 6 + 6 = 16 0bxxxxyyyyyyzzzzzz 0x800~0xFFFF < 0x10000
4 0b11110www 0b10xxxxxx 0b10yyyyyy 0b10zzzzzz 3 + 6 + 6 + 6 = 21 0bwwwxxxxxxyyyyyyzzzzzz 0x10000~0x1FFFFF < 0x200000
相关标签: utf8