用QT,C++语言进行下图所示程序编写,需要分成main,packunpack,widgt三个cpp文件需要完整的编码过程,具体过程或如果有文件,都可上传。用C++写代码,图1为要求,图2为示例
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
//模块ID(1字节)
//数据头(1字节,包含6个数据的bit0+二级IDbit0,顺序从高到低依次为:数据1bit0 数据2bit0....二级IDbit0,最高位bit7=1)
//二级ID(1字节,bit0置1)
//数据6字节(bit0置1)+干扰码6字节(交替排列)
//校验码(1字节)(数据高7位和,包括模块ID高7位+二级ID高7位+数据头高7位)
//总长度4+12=16个字节
#include <iostream>
#include <string>
using namespace std;
/**@brief 编码
@param[in] modId 模块ID
@param[in] subId 二级ID
@param[in] 6字节数据
@param[in] 6字节干扰码
@return 编码后的字符串
*/
char* enCode( char modId, char subId, char data[], char gr[] )
{
int k = 0;
char* package = new char[17];
package[16] = 0;
//模块ID
package[0] = modId;
//数据头
char t = 0x80;
char m;
//1.拼接6个数据的bit0
for (int i = 0; i < 6; i++)
{
m = (data[i] & 0x01);//得到data[i]的bit0
m = m << (6 - i); //m左移6-i位
t += m;
}
//2.拼接二级ID 的bit0
m = (subId & 0x01);
t += m;
package[1] = t;
//二级ID
package[2] = subId | 0x01; //二级ID的bit0置1
//数据+干扰码
k = 3;
for (int i = 0; i < 6; i++)
{
m = data[i] | 0x01; //数据的bit0置1
package[k++] = m;
package[k++] = gr[i]; //干扰码
}
//校验码 package[15] = (模块ID的高7位+二级ID的高7位+数据头的高7位之和)
char p7 = modId & 0xfe; //提取模块ID的高7位
char p6 = subId & 0xfe; //提取二级模块的高7位
char p5 = package[1] & 0xfe; //数据头的高7位
p7 = p7 >> 1; //右移1位
p6 = p6 >> 1;
p5 = p5 >> 1;
package[15] = p7 + p6 + p5;
return package;
}
/**@brief 解码
@param[in] package 需要解码的报文
@param[out] modID 模块ID
@param[out] subID 二级ID
@param[out] data 6字节数据
@param[out] gr 6字节干扰码
@return 解码成功返回1,否则返回0
*/
int deCode(const char* package, char* modId, char* subId, char data[], char gr[])
{
if (strlen(package) != 16) //报文长度16
return 0;
*modId = package[0]; //模块ID
*subId = package[2] & 0xfe; //二级ID,bit0置0
char head = package[1]; //数据头
*subId = (*subId) | (head & 0x01);//head的bit0是二级ID的bit0
head = head>> 1; //右移1位,因为原来最后1位是二级ID的bit0
//数据部分
int k = 14;
for (int i = 5; i >= 0; i--)
{
gr[i] = package[k--];
data[i] = package[k--] & 0xfe; //将data[i]的bit0置0
char t = head & 0x01; //得到最后1位
data[i] = data[i] | t; //修正data[i]的bit0
head = head >> 1;
}
return 1;
}
int main()
{
char data[] = {0x00,0x01,0x6E,0x01,0x70,00};
char gr[] = { 0xfe,0xfe,0xfe,0xfe,0xfe,0xfe };
char modId = 0x12;
char subId = 0x02;
char* p = enCode(modId, subId, data, gr);
printf("模块ID:%02x,二级ID:%02x,", modId & 0xff, subId & 0xff);
cout << "原数据:" ;
for (int i = 0; i < 6; i++)
{
printf("%02x ", data[i] & 0xff);
}
cout << "\n编码后:" << endl;
for (int i = 0; i < 16; i++)
{
char t = p[i];
printf("%02x ", (t & 0xff));
}
//
cout << "\n解码后:" << endl;
char mid = 0, sid = 0, dt[7] = { 0 }, gg[7] = { 0 };
deCode(p, &mid, &sid, dt, gg);
printf("模块ID:%02x\n", mid);
printf("二级id:%02x\n", sid);
printf("数据:");
for (int i = 0; i < 6; i++)
printf("%02x ", dt[i] & 0xff);
return 0;
}
编码:
QByteArray encodePacket(quint8 moduleId, quint8 dataHeader, quint16 secondaryId, const QByteArray &data, const QByteArray &interferenceCode)
{
// 创建一个字节数组来存储编码后的数据包
QByteArray packet;
// 创建一个QDataStream对象来帮助我们写入二进制数据
QDataStream stream(&packet, QIODevice::WriteOnly);
// 将模块ID写入数据流
stream << moduleId;
// 将数据头写入数据流
stream << dataHeader;
// 将二级ID写入数据流
stream << secondaryId;
// 将数据写入数据流
stream.writeRawData(data.constData(), data.size());
// 将干扰码写入数据流
stream.writeRawData(interferenceCode.constData(), interferenceCode.size());
// 计算校验码
quint8 checkSum = calculateCheckSum(packet);
// 将校验码写入数据流
stream << checkSum;
return packet;
}
解码:
bool decodePacket(const QByteArray &packet, quint8 &moduleId, quint8 &dataHeader, quint16 &secondaryId, QByteArray &data, QByteArray &interferenceCode)
{
// 创建一个QDataStream对象来帮助我们读取二进制数据
QDataStream stream(packet);
// 读取模块ID
stream >> moduleId;
// 读取数据头
stream >> dataHeader;
// 读取二级ID
stream >> secondaryId;
// 读取数据和干扰码
data = stream.read(6);
interferenceCode = stream.read(6);
// 读取校验码
quint8 checkSum;
stream >> checkSum;
// 检查校验码是否有效
return checkSum == calculateCheckSum(packet);
}
quint8 calculateCheckSum(const QByteArray &packet)
{
// 校验码是数据高7位的和
quint8 checkSum = 0;
for (int i = 0; i < packet.size(); ++i)
{
checkSum += (packet[i] >> 1);
}
return checkSum;
}
就是解包和拆包呗
编码解码参考资料https://blog.csdn.net/FlushHip/article/details/82498670