中文内容转码UTF8解决方案

2024-05-06 11:18

本文主要是介绍中文内容转码UTF8解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

              在最近的工作中遇到一些中文编码方式的问题,具体描述如下。

              工作内容:审计邮件的内容,并对收发件人进行匹配,若命中则记录邮件内容(数据库中字符串最长1024个字节)到数据库,整个过程编码为UTF8,即需要将邮件内容转码成utf8存储,用到库函数iconv函数转化。

              遇到的问题:在实际网络流量中,用iconv(这个函数的各个参数及返回值详见附录1)转化出现转换失败的问题;即使转换成功,切转化之后的长度大于1024,需要截取1024个字符入库有非法字符的情况,入库失败。

问题分析:

              问题一分析:若邮件长度比较长,在数据包中会进行分片,如图1,2所示,图1是内容分片的第一部分,图2是内容分片的第二部分,我们的系统按照内容分片进行转码,如果一段比较长的邮件内容被分成n(>=2)段,则可能一个中文在数据流中被截断了,也就是说在这个分片的最后和下一份分片的开头,把这两部分组合起来才是一个汉字,故iconv转化失败了,报错。

图1

图2

              问题二分析:因为数据库存储邮件内容的字段有长度限制,所以需要在邮件内容过长的情况下对其进行截取,如果截取存在把一个汉字截成两片的情况就会出现入库报错。如图3所示。

              这说明入库的内容中存在非法字符“\xE6\x95”,数据库报错。根据utf8编码规则(详见附录2),\xE6转化为二进制为11100110,\x95转化为二进制为1001 0101,这说明这个汉字包含三个字节,而因为此汉字的三个字节分别为字符串的第1023和1024和1025个字节,故其被从1024处截断了。

解决方案:

              对于问题1,我们假设一个邮件内容因为长度较长被在数据流中分成了三个流,一个中文在第一个和第二个流之间被截断了,第二个和第三个流被正常分割。因为我们的系统是一个流一个流的处理,这时我们转化第一个流肯定失败,我们的解决方案是第一个流转化失败就先把它存起来,等第二个流来了之后把第一个流和第二个流合并起来进行统一转码,这个时候由于把分割的汉字拼在一起转码成功了。

              当然,存在每一个流里都分割了中文的情况,这个可以按照上述方法,先进行存储然后转化,如果可以都存起来就可以避免中文被分割的情况,从而实现多次存储一次转码的方案。

              对于问题二,我们的解决方案是判断最后一个字节的值,即用它&\0xFF,如果小于128说明此为只有一个字符,应该是一个英文或者一个数字,可以直接截断到此处。如果大于128 小于192则说明次字符不止一个字节,所以一直向前找,找到大于192的为止,这说明这是这个汉字的头一位,直接截取到这个位置就可以了。

如上方法可能存在最后一个字节是本汉字的最后一个字节,应该可以截断,但我们没有而是继续向上截取上一个的情况,因为对于多个字节的情况,最后一个字节和中间的字节都是大于128而小于192的,不好做判断。

 

附件1:

inconv_t cd:函数iconv_open()分配的编码转换句柄。

 

char **restrictinbuf:指向需要编码转换的缓冲区。(其中关键字restrict只用于限定指针;该关键字用于告知编译器,所有修改该指针所指向内容的操作全部都是基于(base on)该指针的,即不存在其它进行修改操作的途径;这样的后果是帮助编译器进行更好的代码优化,生成更有效率的汇编代码。)

 

size_t *restrictinbytesleft:inbuf中还需要编码转换的字节数。

 

char **restrictoutbuf:指向存放转码的缓冲区。

 

size_t *restrictoutbytesleft:outbuf中还可以存放转码的字节数,也就是outbuf中的剩余空间。

 

返回值:是size_t类型的值,若返回值为ret,可以用(ret==-1)判断转码是否成功,-1为不成功

 

附件2:

UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。UTF-8最多可用到6个字节。 
如表: 
1
字节 0xxxxxxx 
2
字节 110xxxxx 10xxxxxx 
3
字节 1110xxxx 10xxxxxx 10xxxxxx 
4
字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 
5
字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
6
字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 
因此UTF-8中可以用来表示字符编码的实际位数最多有31位,即上表中x所表示的位。除去那些控制位(每字节开头的10等),这些x表示的位与UNICODE编码是一一对应的,位高低顺序也相同。 
实际将UNICODE转换为UTF-8编码时应先去除高位0,然后根据所剩编码的位数决定所需最小的UTF-8编码位数。 
因此那些基本ASCII字符集中的字符(UNICODE兼容ASCII)只需要一个字节的UTF-8编码(7个二进制位)便可以表示。 

对于上面的问题,代码中给出的两个字节是 
十六进制:C0 B1 
二进制:11000000 10110001 
对比两个字节编码的表示方式: 
110xxxxx 10xxxxxx 

提取出对应的UNICODE编码: 
00000 110001 

可以看出此编码并非“标准”的UTF-8编码,因为其第一个字节的“有效编码”全为0,去除高位0后的编码仅有6位。由前面所述,此字符仅用一个字节的UTF-8编码表示就够了。 
JAVA
在把字符还原为UTF-8编码时,是按照“标准”的方式处理的,因此我们得到的是仅有1个字节的编码。 

这篇关于中文内容转码UTF8解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/964199

相关文章

2024.6.24 IDEA中文乱码问题(服务器 控制台 TOMcat)实测已解决

1.问题产生原因: 1.文件编码不一致:如果文件的编码方式与IDEA设置的编码方式不一致,就会产生乱码。确保文件和IDEA使用相同的编码,通常是UTF-8。2.IDEA设置问题:检查IDEA的全局编码设置和项目编码设置是否正确。3.终端或控制台编码问题:如果你在终端或控制台看到乱码,可能是终端的编码设置问题。确保终端使用的是支持你的文件的编码方式。 2.解决方案: 1.File -> S

Steam邮件推送内容有哪些?配置教程详解!

Steam邮件推送功能是否安全?如何个性化邮件推送内容? Steam作为全球最大的数字游戏分发平台之一,不仅提供了海量的游戏资源,还通过邮件推送为用户提供最新的游戏信息、促销活动和个性化推荐。AokSend将详细介绍Steam邮件推送的主要内容。 Steam邮件推送:促销优惠 每当平台举办大型促销活动,如夏季促销、冬季促销、黑色星期五等,用户都会收到邮件通知。这些邮件详细列出了打折游戏、

风水研究会官网源码系统-可展示自己的领域内容-商品售卖等

一款用于展示风水行业,周易测算行业,玄学行业的系统,并支持售卖自己的商品。 整洁大气,非常漂亮,前端内容均可通过后台修改。 大致功能: 支持前端内容通过后端自定义支持开启关闭会员功能,会员等级设置支持对接官方支付支持添加商品类支持添加虚拟下载类支持自定义其他类型字段支持生成虚拟激活卡支持采集其他站点文章支持对接收益广告支持文章评论支持积分功能支持推广功能更多功能,搭建完成自行体验吧! 原文

免费内网穿透工具 ,快解析内网穿透解决方案

在IPv4公网IP严重不足的环境下,内网穿透技术越来越多的被人们所使用,使用内网穿透技术的好处有很多。 1:无需公网ip 物以稀为贵,由于可用的公网IP地址越来越少,价格也是水涨船高,一个固定公网IP一年的成本要上万,而使用内网穿透技术则不需要公网IP的支持。 2:提高安全性 使用内网穿透技术,无需在路由器映射端口,我们知道黑客通常会使用端口扫描来寻找攻击对象,不映射端口能大大提高服务器的安全

分布式事务的解决方案(一)

前言应用场景 事务必须满足传统事务的特性,即原子性,一致性,分离性和持久性。但是分布式事务处理过程中, 某些场地比如在电商系统中,当有用户下单后,除了在订单表插入一条记录外,对应商品表的这个商品数量必须减1吧,怎么保证? 在搜索广告系统中,当用户点击某广告后,除了在点击事件表中增加一条记录外, 还得去商家账户表中找到这个商家并扣除广告费吧,怎么保证? 一 本地事务 以用户A

Android 10.0 系统开机重启桌面时钟小部件widget加载慢解决方案

1.前言 在10.0的系统rom产品定制化开发中,在Launcher3桌面系统默认会有时钟widget小部件显示在首屏的,但是发现在开机过程 中会显示的好慢,等进入桌面了 还没显示,所以接下来分析下相关的源码流程,来实现相应的功能 2.系统开机重启桌面时钟小部件widget加载慢解决方案的核心类 frameworks\base\services\appwidget\java\com\andr

【建设方案】基于gis地理信息的智慧巡检解决方案(源文件word)

传统的巡检采取人工记录的方式,该工作模式在生产中存在很大弊端,可能造成巡检不到位、操作失误、观察不仔细、历史问题难以追溯等现象,使得巡检数据不准确,设备故障隐患得不到及时发现和处理。因此建立一套完善的巡检管理系统是企业实现精细化管理的一项重要工作。 基于GIS地理信息系统绘制常规巡检线路,设置线路巡检频率,当线路处于激活状态时,可根据已设置的频率自动生成巡检线路任务,并以消息的形式推送给执行人,

【团队成长】2024-25周周报-业务介绍内容创作

大家好!我们是IndustryOR 团队,致力于分享业界落地的算法技术。欢迎关注微信公众号/知乎/CSDN【运筹匠心】 。 记录人:张哲铭,某互联网大厂算法专家 【团队成长/个人成长】系列的推文会以 【工作周报】 的方式记录IndustryOR团队及其成员的成长过程,请大家一起见证和参与我们团队从0-1-N的发展过程。 记录人顺序:张哲铭-向杜兵-高欣甜-黄世鸿-许佳鸣

uni-pay 2.x:一站式支付解决方案,让支付变得简单高效

一、引言 在移动互联网时代,支付功能已成为各类应用不可或缺的一部分。然而,支付功能的开发往往伴随着复杂的流程和高昂的成本,特别是在对接微信支付、支付宝支付等主流支付渠道时,前端后端的开发工作量和出错率都较高。为了简化这一过程,uni-pay应运而生,并以其高效、易用的特性受到了广大开发者的青睐。最近,uni-pay又升级到了2.x版本,进一步增强了其功能性和易用性。 二、uni-p

八爪鱼现金流-029,网站裂变解决方案,10hongbao

现在完成renwu,可以得10hongbao !!! 八爪鱼现金流 八爪鱼 背景: 个人开发者tuiguang 项目。一个用户推给两个用户,两个用户又分别推给两个用户,就实现了指数级增长。 业务场景分析: 用户zhuce账号 -----> 用户获得tuijian码 -----> 推给其他用户zhuce–>zhuce页面添tuijian码 步骤: 1.用户zhuce,查看活动详情,