目录
1、什么是HEX码
在计算机科学中,"hex码"是"十六进制码"的简称,它是一种表示数字和字符的编码方式。十六进制使用16个符号(0-9和A-F)来表示数值,相对于常见的十进制(使用0-9)和二进制(使用0和1)编码,它在表示较大的数值时更加紧凑。
每个十六进制符号对应的二进制表示是4位,因此一个十六进制数位可以精确地表示4个二进制位。这对于计算机中的内存寻址和数据存储非常有用。
例如,十进制数值10在十六进制中表示为A,而十进制数值15在十六进制中表示为F。而十六进制数值1A对应的十进制数值是26。
另一个常见的用途是在颜色编码中。在HTML和CSS中,颜色经常使用六位的十六进制码来表示,例如#FF0000表示红色。
总之,十六进制码是计算机科学中一种用于表示数字和字符的编码方式,特点是紧凑且易于转换为二进制或者其他进制。
2、hex码的转换
2.1 十六进制数怎么转换成二进制数
比如0xAF 占一个字节,一个字节是8位,A代表高四位,F代表低四位,先转F,我们都知道F代表十进制0-15,而F对应的十进制是15,按照二进制8421,对照,8+4+2+1,则F对应的1111.
而A是0.1.2.3.4.5.6.7.8.9.A.B.C.D.E.F中相当于十进制的10,则8+0+2+0,对应二进制1010,
0xAF对应的二进制数10101111,0x代指这个数是十六进制数,没有其他任何含义。
2.2 二进制数怎么转成十六进制数
1100 0110
以四个为一组,1100 对应8421的十进制 也就是12,12在十六进制中用C
0110 对应8421的十进制数,也就是4+2为6,6在十六进制中还是6
即 1100 0110= 0xC6
2.3 用十六进制的好处
数据的传输传输的都是字节,udp一次最多传输差不多65507字节,UDP每次传输的数据量: UDP在一个数据包中可以传输的数据量不是固定的,理论上最多可以传输65507字节(65,535 - 8字节UDP头 - 20字节IP头)的数据。
1、数据量少
十六进制两个字符才占一个字节,比如 C2 ,而比如一个英文字母a占了一个字节。
2、方便转换
十六进制一般都是单片机通信使用,往往需要转换成二进制提取最高位,或者两个字符做判断代表不同的信息。
3、节省空间和时间
我们都知道计算机实际操作就是二进制代码,而十六进制是最接近二进制的,直接操作十六进制代码无论是在时间上或者空间上,都得到节约。
3、如何使用QT解析十六进制代码(包含代码)
通过udp来接受hex码,为何不使用串口的模块来接收hex呢,是因为我使用的qt版本没有串口模块。
所以需要下位机串口转网口,我的客户端使用udp来处理hex码。
3.1 了解qt的udp运行机制
在Qt中,UDP监听是异步的。这意味着当您使用readyRead
信号连接到槽函数时,当UDP套接字(或接收器)收到数据时,将立即发出信号,而不会阻塞程序的其他部分。这是Qt的事件驱动架构的核心之一。
这种异步机制允许您同时监听UDP数据,同时保持您的应用程序的其他部分对用户输入和其他事件的响应。这样,即使您在监听UDP数据时,用户界面仍然可以保持响应,不会被阻塞。
因此,长时间的UDP监听不会影响用户界面的响应性,因为当数据到达时,会生成一个异步信号,而不会阻塞主线程。
然而,如果在槽函数中执行耗时的操作,可能会影响用户界面的响应性。如果涉及到复杂的计算或需要大量的时间来执行,您可能需要考虑在另一个线程中处理数据,以确保不会阻塞主线程。这可以通过Qt的多线程机制来实现。
总之,UDP监听是异步的,不会阻塞用户界面的响应。但是,请确保在处理接收到的数据时,不会执行耗时的操作,以避免影响应用程序的性能和用户体验。
3.2 怎么处理接收到的hex数据
在类的构造函数中,接收数据
m_receiver=new QUdpSocket(this);
// 绑定接收端,ShareAddress 允许多接收端绑定 1234 端口
m_receiver->bind(QHostAddress("127.0.0.1"), 1234, QUdpSocket::ShareAddress);
//当接收端接收到数据时,就会发送readRead信号
connect(m_receiver,SIGNAL(readyRead()),this,SLOT(processData()));
接收数据的槽函数
void yourclass::processData()
{
while (m_receiver->hasPendingDatagrams()) {
QByteArray datagram;
datagram.resize(m_receiver->pendingDatagramSize());
QHostAddress senderAddress;
quint16 senderPort;
m_receiver->readDatagram(datagram.data(), datagram.size(), &senderAddress, &senderPort);
// 将十六进制字节转换为十六进制字符串
hexString = QString::fromLatin1(datagram.toHex());
// 打印接收到的数据
qDebug() << "Received data from" << senderAddress.toString() << "port" << senderPort << ":" << hexString;
}
}
4、怎么对十六进制的字符串进行按照字节分割,获取到数据
包含的头文件:
#include <QByteArray>
#include <QChar>
#include<QString>
#include <QUdpSocket>
note:请包含相对应的模块 ,udp需要包含网络的模块
4.1 取出字节
通用的方法:
i从0开始索引
比如十六进制字符串 44 33 E1 F2
想取出F2
则 chardata(hexString,3)
返回的字符串QString会自动变为小写
做判断: if(chardata(hexString,3)=="f2")
QString yourclass::chardata(const QString &hexString,const int &i) //取出字节
{
QString Chars = hexString.mid(i * 2,2);
return Chars;
}
4.2 取出字节中的字符
i从0开始索引
比如十六进制字符串 44 33 E1 F2
想取出E
bytedata((hexString,4)
QString yourclass::bytedata(const QString &hexString,const int &i) //两个字符组成一个字节
{
QChar byteChar = hexString.at(i);//从0开始索引
return byteChar;
}
4.3 转换成二进制取出最高位
bool yourclass::MSBbitdata(const QString &hexString,const int &i)//哪一个字符的最高位 从0开始索引字符
{
QChar byteChar = hexString.at(i); // 从0开始索引,获取十六进制字符
QString binaryString = QString::number(byteChar.digitValue(), 2); // 转换为二进制字符串
QChar mostSignificantBit = binaryString.at(0); // 获取最高位
if(mostSignificantBit=='1')
{
return true;
}
else
{
return false;
}
}
4.4 十六进制的字符怎么转换成十进制数
比如:取出4-7字节的代表十六进制的字符
并将取出的字符转换成十进制数
4-7 OO OF 42 40
1 000 000=00 0F 42 40
QString frequencydata = hexString.mid(8,8);
bool ok;
uint decimalValue = frequencydata.toUInt(&ok, 16);
if (ok) {
qDebug() << "Hex:" << frequencydata << " -> Decimal:" << decimalValue;
} else {
qDebug() << "Failed to convert hex to decimal.";
}
5、注意点
// 将十六进制字节转换为十六进制字符串
hexString = QString::fromLatin1(datagram.toHex());
hexString是一个QString的类型,是专属于QT中的字符串。
这里的十六进制字节转换成十六进制字符串,所以建议使用qt的方法来处理转换之后的字符串,所占字节跟原来的传过来的数据空间相比,是原来的2倍。
转换之后的一个字符就占一个字节了。
转换之后的想要做判断的字符判断的时候,将字符改成小写,大写不能识别了。