带你读《全景揭秘字符编码》之十:常见字符编码4:UNICODE(9)

简介: 带你读《全景揭秘字符编码》之十:常见字符编码4:UNICODE(9)

带你读《全景揭秘字符编码》之十:常见字符编码4:UNICODE(8) https://developer.aliyun.com/article/1240879?groupCode=tech_library


10.5.2程序算法


用文字不太好描述算法结构,我们就直接来欣赏一下UTF-8鼻祖写的这段解析代码,这是Ken Thompson(B语言、C语言的作者、Unix之父)和 Rob Pike 用一个晚上写出来的编解码算法,代码非常简短精炼,为了方便阅读我加了注释解读。


typedefstruct

{

 intcmask; //前缀码掩码

 intcval;  //前缀码

 intshift; //移动位数

 longlmask; //Unicode值掩码

 longlval;  //Unicode下限值

} Tab;

 

staticTab  tab[] =

{

 0x80, 0x00, 0*6, 0x7F,       0,         /* 1 byte sequence */

 0xE0, 0xC0, 1*6, 0x7FF,      0x80,      /* 2 byte sequence */

 0xF0, 0xE0, 2*6, 0xFFFF,     0x800,     /* 3 byte sequence */

 0xF8, 0xF0, 3*6, 0x1FFFFF,   0x10000,   /* 4 byte sequence */

 0xFC, 0xF8, 4*6, 0x3FFFFFF,  0x200000,  /* 5 byte sequence */

 0xFE, 0xFC, 5*6, 0x7FFFFFFF, 0x4000000, /* 6 byte sequence */

 0, /* end of table */

};

 

/**

* 把一个多字节序列转换为一个宽字符

*

* @param p 存放计算后的unicode值

* @param s 需要解析的UTF-8字节序列

* @param n 字节长度

* @return 解析的字节长度

*/

intmbtowc(wchar_t*p, char*s, size_tn)

{

 longl;  intc0, c, nc;  Tab *t;

 if(s == 0) return0;

 nc = 0;

 //异常校验(可不用关注)

 if(n <= nc) return-1;

 //c0 此处备份一下首字节,后续需要用到前缀码

 c0 = *s & 0xff;

 //l 保存 Unicode 结果

 l = c0;

 /* 遍历tab,从单字节结构->2字节结构->..依次检查找到对应tab */

 for(t=tab; t->cmask; t++) {

   //字节数+1,字节数和tab结构是对应的,也就是当nc=1时 tab结构是单字节,nc=2是tab是两字节

   nc++;

   /* 判断前缀码跟当前的tab是否一致, 如果一致计算最终unicode值并返回*/

   if((c0 & t->cmask) == t->cval) {

     //通过 & Unicode有效值掩码,移除高位前缀码,得到最终unicode值

     l &= t->lmask;

     //异常校验

     if(l < t->lval) return-1;

     //保存结果并反回

     *p = l;

     returnnc;

   }

   //异常校验

   if(n <= nc) return-1;

   //读取下个字节;如果上面判断前缀码不一致,说明需要再读取下个字节

   s++;

   //计算有效位的值,目的是去除UTF-8 编码从第二个字节开始的高两位10

   // 例如 s=10101111、0x80=10000000 计算结果是00101111,这样就去除了高位前缀10

   c = (*s ^ 0x80) & 0xFF;

   //异常校验

   if(c & 0xC0) return-1;

   //重新计算unicode值,根据UTF-8规则c只有低 6 位有效,所以通过移位把c填入到l的低6位

   l = (l<<6) | c;

 }

 //返回异常

 return-1;

}



带你读《全景揭秘字符编码》之十:常见字符编码4:UNICODE(10) https://developer.aliyun.com/article/1240875?groupCode=tech_library

相关文章
|
Java Android开发 C++
Rockchip系列之CAN 新增framework系统jni接口访问(2)
Rockchip系列之CAN 新增framework系统jni接口访问(2)
198 3
|
开发工具 git
Git添加子模块(submodule)
Git添加子模块(submodule)
943 0
|
安全 搜索推荐 Shell
看完这篇 教你玩转渗透测试靶机vulnhub——DC7
看完这篇 教你玩转渗透测试靶机vulnhub——DC7
800 0
看完这篇 教你玩转渗透测试靶机vulnhub——DC7
|
SQL Java 数据库连接
Mybatis多表关联查询与动态SQL(上)
Mybatis多表关联查询与动态SQL
437 0
|
开发框架 UED 开发者
鸿蒙next版开发:ArkTS组件通用属性(显隐控制)
在HarmonyOS 5.0中,ArkTS引入了显隐控制属性,允许开发者通过`visibility`属性控制组件的显示与隐藏,优化用户体验和应用性能。本文详细解析了`visibility`属性的三种状态(Visible、Hidden、None)及其应用场景,并通过示例代码展示了如何使用显隐控制属性,避免组件频繁创建和销毁,提升性能。
918 8
|
机器学习/深度学习 边缘计算 运维
智能化运维的演进之路:从脚本工具到AIOps
在数字化浪潮下,企业运维管理正经历一场深刻的变革。本文将探索智能化运维的发展脉络,从最初的脚本工具应用到当下的AIOps实践,揭示这一过程中的关键技术进步和理念更新。我们将通过具体案例,展示如何利用大数据、机器学习等技术提升运维效率,降低人力成本,并预测未来运维领域的发展趋势。
|
消息中间件
RabbitMQ如何支持事务性消息的发送和接收
RabbitMQ消息的发送和接收
491 0
|
Web App开发 前端开发 iOS开发
快来让你的网页色彩绚丽--linear-gradient与radial-gradient
CSS属性 linear-gradient 与 radial-gradient
910 0
快来让你的网页色彩绚丽--linear-gradient与radial-gradient
|
人工智能 小程序 数据安全/隐私保护
十分钟带你彻底告别翻来覆去找ChatGPT提示词模版
十分钟带你彻底告别翻来覆去找ChatGPT提示词模版
|
SQL 安全 数据库
[RCTF2015]EasySQL1 题目分析与详解
[RCTF2015]EasySQL1 题目分析与详解

热门文章

最新文章