压力算法移植前

This commit is contained in:
2026-06-29 14:54:30 +08:00
parent 507781d127
commit ef2eecf972
1652 changed files with 312373 additions and 29 deletions
+645
View File
@@ -0,0 +1,645 @@
#include "rfidfunction.h"
#include "sm3.h"
#include "sm4.h"
#include <QTime>
#include <QCoreApplication>
// 计算校验和并输出
void RFIDFunction::CheckSumOut(unsigned char* buf, unsigned char len)
{
unsigned char i;
unsigned char checksum;
checksum = 0;
for (i = 0; i < (len - 1); i++)
{
checksum ^= buf[i]; // 逐位异或计算校验和
}
buf[len - 1] = (unsigned char)~checksum; // 取反作为校验和
}
// 检查输入的校验和是否正确
bool RFIDFunction::CheckSumIn(unsigned char* buf, unsigned char len)
{
unsigned char i;
unsigned char checksum;
checksum = 0;
for (i = 0; i < (len - 1); i++)
{
checksum ^= buf[i]; // 逐位异或计算校验和
}
if (buf[len - 1] == (unsigned char)~checksum) // 比较校验和
{
return true; // 校验和正确
}
return false; // 校验和错误
}
// 将十六进制字符串转换为字节数组
void hexStrToByte(const QByteArray& hexIn, unsigned char* dest)
{
int sourceLen = hexIn.size();
unsigned char* source = (unsigned char*)hexIn.constData();
short i;
unsigned char highByte, lowByte;
for (i = 0; i < sourceLen; i += 2)
{
highByte = toupper(source[i]); // 高位
lowByte = toupper(source[i + 1]); // 低位
if (highByte > 0x39)
{
highByte -= 0x37; // A-F转换
}
else
{
highByte -= 0x30; // 0-9转换
}
if (lowByte > 0x39)
{
lowByte -= 0x37; // A-F转换
}
else
{
lowByte -= 0x30; // 0-9转换
}
dest[i / 2] = (highByte << 4) | lowByte; // 合并高低位
}
return;
}
// 检测输入的字符是否是有效的16进制字符
bool isValidHex(const QByteArray& input)
{
int length = input.size(); // 获取输入的长度
for (int i = 0; i < length; ++i) // 使用传统的for循环
{
char c = input[i]; // 获取当前字符
// 检查字符是否在0-9, A-F, a-f范围内
if (!((c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'F') ||
(c >= 'a' && c <= 'f')))
{
return false; // 如果有无效字符,返回false
}
}
return true; // 所有字符均有效,返回true
}
void sleepMs(unsigned int msec)
{
QTime dieTime = QTime::currentTime().addMSecs(msec);
while( QTime::currentTime() < dieTime )
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
RFIDFunction::RFIDFunction(QObject *parent)
: QObject(parent),m_SerialPort(NULL)
{
m_SerialSate = initSerialPortAndOpen("COM3"); // 初始化串口
}
RFIDFunction::~RFIDFunction()
{
if (m_SerialPort) {
if (m_SerialPort->isOpen()) {
m_SerialPort->close();
}
delete m_SerialPort;
m_SerialPort = nullptr;
}
}
/***
* @描述 : 创建读写卡的密码(Key_A和Key_B)
* @入参 : info 生成密码的数据
* @输出 : 无
* @返回 : 密钥的原始数据
*/
const QByteArray RFIDFunction::createPassword(const QByteArray& info)
{
if (info.isEmpty())
{
return ""; // 如果输入为空,返回空
}
int inputSize = info.size();
if (inputSize > 8192)
{
return ""; // 如果输入大小超过限制,返回空
}
//先用SM3对原始数据进行哈希生成
unsigned char hashDataOrigin[32] = { 0 };
SM3::sm3Hash((unsigned char*)info.data(), inputSize, hashDataOrigin); // 生成哈希
//接着使用哈希生成SM4加密密钥
unsigned char sm4Key[16] = { 0 };
unsigned char sm4IV[16] = { 0 };
int index_1 = 0;
int index_2 = 0;
for (int i = 0; i < 32; i++)
{
if (i % 2 == 0)
{
sm4Key[index_1++] = hashDataOrigin[i]; // 偶数位作为SM4密钥
}
else
{
sm4IV[index_2++] = hashDataOrigin[i]; // 奇数位作为SM4初始向量
}
}
//再用SM4对原始数据进行加密
unsigned char out[8192] = {0};
sm4_context sm4Ctx;
SM4::sm4_setkey_enc(&sm4Ctx, sm4Key); // 设置SM4加密密钥
SM4::sm4_crypt_cbc(&sm4Ctx, SM4_ENCRYPT, inputSize, sm4IV, (unsigned char*)info.data(), out); // 执行SM4加密
//最后再用SM3对加密后的数据取哈希
unsigned char hashEncrypted[32] = { 0 };
SM3::sm3Hash(out, inputSize, hashEncrypted); // 生成加密数据的哈希
index_1 = 0;
char key[16] = { 0 };
for (int i = 0; i < 32; i++)
{
if (i % 2 != 0)//取哈希的奇数位作为最终的密码
{
key[index_1++] = hashEncrypted[i];
}
}
return QByteArray(key,16).toHex(); // 返回最终的密码
}
bool RFIDFunction::getSerialState()
{
return m_SerialSate; // 返回串口状态
}
RFIDFunction::ErrorCode RFIDFunction::initSerialPortAndOpen(const QString& portName,
BaudRateType baudRate,
DataBitsType setDataBits,
StopBitsType stopBits,
ParityType parity)
{
m_SerialPort = new Posix_QextSerialPort("/dev/ttyO3",QextSerialBase::Polling); // 创建串口对象
m_SerialPort->setPortName(portName); // 设置串口名称
m_SerialPort->setBaudRate((BaudRateType)baudRate); // 设置波特率
m_SerialPort->setDataBits(setDataBits); // 设置数据位
m_SerialPort->setStopBits(stopBits); // 设置停止位
m_SerialPort->setParity(parity); // 设置校验位
m_SerialPort->setFlowControl(FLOW_OFF);
if (m_SerialPort->open(QIODevice::ReadWrite)) // 打开串口
{
return Serial_Error; // 打开失败,返回串口错误
}
return No_Error; // 打开成功,返回无错误
}
RFIDFunction::ErrorCode RFIDFunction::setOriginPassword(const QByteArray& psw)
{
unsigned char com[32] = { 0 }; // 命令数组
com[0] = 0x03; // 命令头
com[1] = 0x0B; // 数据长度
com[2] = 0xC4; // 命令类型
com[3] = 0x20; // 额外数据
unsigned char hexOut[32] = { 0 }; // 存储转换后的十六进制数据
hexStrToByte(psw, hexOut); // 将密码转换为字节数组
memcpy(com + 4, hexOut, 6); // 将密码添加到命令中
CheckSumOut(com, com[1]); // 计算校验和
//QByteArray AAA = QByteArray((char*)com, com[1]).toHex(); // 转换为十六进制字符串
if (m_SerialPort->isOpen()) // 检查串口是否打开
{
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
if (len != com[1]) // 检查发送长度
{
return Send_Data_Error; // 发送错误
}
// 等待请求完成
sleepMs(200);
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
unsigned char revData[32] = { 0 }; // 存储返回数据
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
if ((revData[0] == 0x03) && (revData[1] == 0x08) && (revData[2] == 0xC4) && (revData[3] == 0x20)) //判断是否为写数据返回的数据包
{
bool status = CheckSumIn(revData, revData[1]); //计算校验和
if (status)
{
if (revData[4] == 0x00) //写数据块成功
{
return No_Error; // 返回无错误
}
}
else
{
return Received_Data_Check_Error; // 校验和错误
}
}
else
{
return Received_Data_Error; // 返回数据错误
}
}
return Serial_Error; // 串口错误
}
RFIDFunction::ErrorCode RFIDFunction::setWriteAndReadPassword(const QByteArray& writePassword, const QByteArray& readPassword, KeyFunction keyFunc)
{
if (writePassword.isEmpty() || readPassword.isEmpty())
{
return Data_Is_Empty_Error; // 如果密码为空,返回错误
}
unsigned char com[32] = { 0 }; // 命令数组
com[0] = 0x03; // 命令头
com[1] = 0x15; // 数据长度
com[2] = 0xC3; // 命令类型
com[3] = 0x20; // 额外数据
unsigned char hexOut[32] = { 0 }; // 存储转换后的十六进制数据
hexStrToByte(writePassword.toHex(), hexOut); // 将写密码转换为字节数组
memcpy(com + 4, hexOut, 6); // 将写密码添加到命令中
switch (keyFunc) // 根据密钥功能设置命令
{
case RFIDFunction::KeyA_Same_KeyB:
/*
* 控制如下:KEYA,KEYB 可以用来读 、写 、增值 、减值 、更改扇区密钥
*/
com[10] = 0xFF; // 设置KEYA和KEYB相同
com[11] = 0x07; // 设置权限
com[12] = 0x80; // 设置操作
com[13] = 0x69; // 设置结束标志
break;
case RFIDFunction::KeyB_Control_KeyA:
/*
控制如下:KEYA 可以读数据块 、减值 、查询余额
KEYB 可以读写数据块 、增值 、减值 、查询余额
KEYA 、KEYB 不可读,KEYA,KEYB 由 KEYB 修改
*/
com[10] = 0x08; // 设置KEYB控制KEYA
com[11] = 0x77; // 设置权限
com[12] = 0x8F; // 设置操作
com[13] = 0x69; // 设置结束标志
break;
default:
break;
}
memset(hexOut, 0, 32); // 清空hexOut
hexStrToByte(readPassword.toHex(), hexOut); // 将读密码转换为字节数组
memcpy(com + 14, hexOut, 6); // 将读密码添加到命令中
CheckSumOut(com, com[1]); // 计算校验和
QByteArray AAA = QByteArray((char*)com, com[1]).toHex(); // 转换为十六进制字符串
if (m_SerialPort->isOpen()) // 检查串口是否打开
{
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
if (len != com[1]) // 检查发送长度
{
return Send_Data_Error; // 发送错误
}
// 等待请求完成
sleepMs(200);
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
unsigned char revData[32] = { 0 }; // 存储返回数据
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
if ((revData[0] == 0x03) && (revData[1] == 0x08) && (revData[2] == 0xC3) && (revData[3] == 0x20)) //判断是否为写数据返回的数据包
{
bool status = CheckSumIn(revData, revData[1]); //计算校验和
if (status)
{
if (revData[4] == 0x00) //写数据块成功
{
return No_Error; // 返回无错误
}
}
else
{
return Received_Data_Check_Error; // 校验和错误
}
}
else
{
return Received_Data_Error; // 返回数据错误
}
}
return Serial_Error; // 串口错误
}
RFIDFunction::ErrorCode RFIDFunction::setEncryptedBlock(KeyType type, ControlBlock block)
{
unsigned char com[32] = { 0 }; // 命令数组
com[0] = 0x01; // 命令头
com[1] = 0x08; // 数据长度
switch (type)//只有两种密码,A和B
{
case RFIDFunction::KEY_A:
com[2] = 0xA5; // 设置为KEY_A
break;
case RFIDFunction::KEY_B:
com[2] = 0x5A; // 设置为KEY_B
break;
default:
com[2] = 0xA5; // 默认设置为KEY_A
break;
}
com[3] = 0x20; // 额外数据
memcpy(com + 4, &block, 1); // 将加密块添加到命令中
com[5] = 0x01;//蜂鸣器开 0x00不开
com[6] = 0x00;//保留
CheckSumOut(com, com[1]); // 计算校验和
QByteArray AAA = QByteArray((char*)com, com[1]).toHex(); // 转换为十六进制字符串
if (m_SerialPort->isOpen()) // 检查串口是否打开
{
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
if (len != com[1]) // 检查发送长度
{
return Send_Data_Error; // 发送错误
}
// 等待请求完成
sleepMs(200);
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
unsigned char revData[32] = { 0 }; // 存储返回数据
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
if ((revData[0] == 0x01) && (revData[1] == 0x08) && (revData[2] == com[2]) && (revData[3] == 0x20)) //判断是否为写数据返回的数据包
{
bool status = CheckSumIn(revData, revData[1]); //计算校验和
if (status)
{
if (revData[4] == 0x00) //写数据块成功
{
return No_Error; // 返回无错误
}
}
else
{
return Received_Data_Check_Error; // 校验和错误
}
}
else
{
return Received_Data_Error; // 返回数据错误
}
}
return Serial_Error; // 串口错误
}
RFIDFunction::ErrorCode RFIDFunction::writeDataToBlock(KeyType type, DataBlock block, const QByteArray& data)
{
if (data.isEmpty())
{
return Data_Is_Empty_Error; // 如果数据为空,返回错误
}
unsigned char com[32] = { 0 }; // 命令数组
com[0] = 0x01; // 命令头
com[1] = 0x17; // 数据长度
switch (type)//只有两种密码,A和B
{
case RFIDFunction::KEY_A:
com[2] = 0xA4; // 设置为KEY_A
break;
case RFIDFunction::KEY_B:
com[2] = 0x5B; // 设置为KEY_B
break;
default:
com[2] = 0xA4; // 默认设置为KEY_A
break;
}
com[3] = 0x20; // 额外数据
memcpy(com + 4, &block, 1); // 将数据块添加到命令中
com[5] = 0x01;//蜂鸣器开 0x00不开
unsigned char hexOut[32] = { 0 }; // 存储转换后的十六进制数据
memset(hexOut, 0, 32); // 清空hexOut
if (!isValidHex(data)) // 检查数据是否合法
{
return Data_Is_Illegal_Error; // 数据非法
}
hexStrToByte(data, hexOut); // 将数据转换为字节数组
memcpy(com + 6, hexOut, 16); // 将数据添加到命令中
CheckSumOut(com, com[1]); // 计算校验和
if (m_SerialPort->isOpen()) // 检查串口是否打开
{
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
if (len != com[1]) // 检查发送长度
{
return Send_Data_Error; // 发送错误
}
// 等待请求完成
sleepMs(200);
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
unsigned char revData[32] = { 0 }; // 存储返回数据
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
if ((revData[0] == 0x01) && (revData[1] == 0x08) && (revData[2] == com[2]) && (revData[3] == 0x20)) //判断是否为写数据返回的数据包
{
bool status = CheckSumIn(revData, revData[1]); //计算校验和
if (status)
{
if (revData[4] == 0x00) //写数据块成功
{
return No_Error; // 返回无错误
}
}
else
{
return Received_Data_Check_Error; // 校验和错误
}
}
else
{
return Received_Data_Error; // 返回数据错误
}
}
return Serial_Error; // 串口错误
}
RFIDFunction::ErrorCode RFIDFunction::readDataFromBlock(KeyType type, DataBlock block, QByteArray& data)
{
unsigned char com[32] = { 0 }; // 命令数组
com[0] = 0x01; // 命令头
com[1] = 0x08; // 数据长度
switch (type)//只有两种密码,A和B
{
case RFIDFunction::KEY_A:
com[2] = 0xA3; // 设置为KEY_A
break;
case RFIDFunction::KEY_B:
com[2] = 0x5C; // 设置为KEY_B
break;
default:
com[2] = 0xA3; // 默认设置为KEY_A
break;
}
com[3] = 0x20; // 额外数据
memcpy(com + 4, &block, 1); // 将数据块添加到命令中
com[5] = 0x01;//蜂鸣器开 0x00不开
com[6] = 0x00;//保留
CheckSumOut(com, com[1]); // 计算校验和
if (m_SerialPort->isOpen()) // 检查串口是否打开
{
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
if (len != com[1]) // 检查发送长度
{
return Send_Data_Error; // 发送错误
}
// 等待请求完成
sleepMs(200);
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
//QByteArray AAA = readData.toHex(); // 转换为十六进制字符串
unsigned char revData[32] = { 0 }; // 存储返回数据
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
if ((revData[0] == 0x01) && (revData[1] == 0x16) && (revData[2] == com[2]) && (revData[3] == 0x20)) //判断是否为写数据返回的数据包
{
bool status = CheckSumIn(revData, revData[1]); //计算校验和
if (status)
{
if (revData[4] == 0x00) //写数据块成功
{
data = QByteArray::fromHex(readData.mid(3,16));
return No_Error; // 返回无错误
}
}
else
{
return Received_Data_Check_Error; // 校验和错误
}
}
else
{
return Received_Data_Error; // 返回数据错误
}
}
return Serial_Error; // 串口错误
}
RFIDFunction::ErrorCode RFIDFunction::setWorkMode(WorkMode mode, DataBlock block, UploadMode uploadMode)
{
unsigned char com[32] = { 0 }; // 命令数组
com[0] = 0x03; // 命令头
com[1] = 0x08; // 数据长度
com[2] = 0xC1; // 工作模式
com[3] = 0x20; // 设备号数据
memcpy(com + 4, &mode, 1); // 将工作模式添加到命令中
switch (mode)
{
case RFIDFunction::Command_Mode:
com[5] = 0x00;
com[6] = 0x00;
break;
case RFIDFunction::Auto_Read_Card_Num_Mode:
com[5] = 0x00;
com[6] = uploadMode;
break;
case RFIDFunction::Auto_Read_Data_Mode:
case RFIDFunction::Auto_Read_Card_Num_Data_Mode:
default:
com[5] = block;
com[6] = uploadMode;
break;
}
CheckSumOut(com, com[1]); // 计算校验和
if (m_SerialPort->isOpen()) // 检查串口是否打开
{
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
if (len != com[1]) // 检查发送长度
{
return Send_Data_Error; // 发送错误
}
// 等待请求完成
sleepMs(200);
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
QByteArray AAA = readData.toHex(); // 转换为十六进制字符串
unsigned char revData[32] = { 0 }; // 存储返回数据
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
if ((revData[0] == 0x03) && (revData[1] == 0x08) && (revData[2] == com[2]) && (revData[3] == 0x20)) //判断是否为写数据返回的数据包
{
bool status = CheckSumIn(revData, revData[1]); //计算校验和
if (status)
{
if (revData[4] == 0x00) //写数据块成功
{
return No_Error; // 返回无错误
}
}
else
{
return Received_Data_Check_Error; // 校验和错误
}
}
else
{
return Received_Data_Error; // 返回数据错误
}
}
return Serial_Error; // 串口错误
}
RFIDFunction::ErrorCode RFIDFunction::getReaderAddress(QByteArray& psw)
{
unsigned char com[32] = { 0 }; // 命令数组
com[0] = 0x02; // 命令头
com[1] = 0x08; // 数据长度
com[2] = 0xB0; // 命令类型
com[3] = 0x00; // 额外数据
com[4] = 0x00; // 额外数据
com[5] = 0x00; // 额外数据
com[6] = 0x00; // 额外数据
CheckSumOut(com, com[1]); // 计算校验和
QByteArray AAA = QByteArray((char*)com, com[1]).toHex(); // 转换为十六进制字符串
if (m_SerialPort->isOpen()) // 检查串口是否打开
{
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
if (len != com[1]) // 检查发送长度
{
return Send_Data_Error; // 发送错误
}
// 等待请求完成
sleepMs(200);
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
unsigned char revData[32] = { 0 }; // 存储返回数据
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
if ((revData[0] == 0x02) && (revData[1] == 0x08) && (revData[2] == com[2])) //判断是否为写数据返回的数据包
{
bool status = CheckSumIn(revData, revData[1]); //计算校验和
if (status)
{
if (revData[4] == 0x00) //写数据块成功
{
psw = QByteArray::fromHex(QByteArray(revData[5], 1));
return No_Error; // 返回无错误
}
}
else
{
return Received_Data_Check_Error; // 校验和错误
}
}
else
{
return Received_Data_Error; // 返回数据错误
}
}
return Serial_Error; // 串口错误
}