ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Qt ASCII转Unicode再转中文

2021-09-30 18:02:33  阅读:222  来源: 互联网

标签:15 Qt 16 Unicode 串口 ASCII 字节


Qt ASCII转Unicode再转中文


文章目录

1. 前言

这里主要是读取二代身份证的时候的一个协议处理,目前接触了两种模块,协议有一些差异。这里举下解析过程的例子来说明一下这个转换。

2. 示例及转换过程

一般二代证的解析结果中名字占三十个字节,但是这个三十字节不同模块返回会有一些差异,因为直接结果是ASCII,比如汉字“郑”的转成ASCII码为:“\u90D1”,b部分模块是直接返回两个字节0x90和0xd1,但是一些模块是存储成4个字节,而且串口读取到的是16进制码,所以就成了0x44(D)、0x31(1)、0x39(9)、0x30(0),这两种情况下,从串口读取到数据到转换为实际汉字,比较绕,这里分别说明一下转换过程。

2.1 ASCII码形式

这种的有60个字节,可以转换成30字节,再转15字节,也可以直接根据字符将60字节4字节划分成15部分分别处理,将ASCII拆分回复,这种情况不好理解,但是容易看出来,我们通过QByteArray接收到串口数据后直接打印显示的就是ASCII,可以直接打印出“D190”,我们通过串口接收后打印:

QBytearray readBuff;
readBuff = serialPort.readAll();

qDebug()<<readBuff;

这时我们通过ASCII转中文的在线转换工具可以看出来结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mr1Asygc-1632995585382)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20210930171446284.png)]

然后提取出来这60个字节(以ASCII码看是30字节,但是每一个字符占2个字节,就像“D1”,实际D和1每个的存储都需要占用一个字节),然后使用如下方式转换成汉字,而且每两个ASCII字节组成一个汉字,返回的字节高低字节还需要互换:

QByteArray tmp;

for (int i = 0; i < 59; i++) {
    tmp[i] = g_IDNumCardInfo[beginOffset + i];
    tmp[i + 1] = g_IDNumCardInfo[beginOffset + i + 1];
    //        qDebug() << tmp[i] << tmp[i + 1];
}
qDebug() << tmp << tmp.size();

QString nameRes;
for (int i = 0; i < 15; i++) {
    bool ok;
    QByteArray byte;
    //高低字节互换
    byte[0] = tmp[2 + 4 * i];
    byte[1] = tmp[3 + 4 * i];
    byte[2] = tmp[0 + 4 * i];
    byte[3] = tmp[1 + 4 * i];
    //        qDebug() << "file:" << __FILE__ << "line:" << __LINE__ << byte;
    auto *unicode = new QChar[1];

    unicode[0] = byte.toInt(&ok, 16);
    nameRes.append(QString::fromRawData(unicode, 1));
}

qDebug() << "file:" << __FILE__ << "line:" << __LINE__ << "名字:" << nameRes;

2.2 16进制字节

这种的30个字节再组合成15个字节进行转换即可,这种的实际上相当于已经做了一层封装,将ASCII的两个字符字节组合成了一个字节,这种的存储的时候直接高第字节互换然后存储到ushort数组中,然后直接再转成字符串就可以了:

ushort name[15];

for(int i = 0; i < 15; i++) {
    name[i] = g_IDNumCardInfo[8+2*i+1] << 8;
    name[i] = name[i] + (g_IDNumCardInfo[8+2*i] & 0x00ff);

    qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<<QString().sprintf("%02x",name[i]);
}

QString nameRes = QString::fromUtf16(name, 15);
qDebug()<<"file:"<<__FILE__<<"line:"<<__LINE__<< nameRes;

3. 最后

每两个字节代表 1 个汉字的 Unicode 码,低位在前,比如90D1两个字节,但是9、0、d、1这四个字符传输时根据情况可以两两组合分两字节传输(0x90,0xD1)也可以不组合分四个字节传输(可以以ASCII当成字符传0x39、0x30、0x44、0x31,还可以直接以16进制样式传0x09、0x00、0x0d、0x01)。

标签:15,Qt,16,Unicode,串口,ASCII,字节
来源: https://blog.csdn.net/weixin_39510813/article/details/120570649

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有