1、crc校验类代码如下:
头文件
#ifndef CRC16CHECK_H
#define CRC16CHECK_H
/**
* @file crc16check.h
* @brief 对16位crc校验进行了封装
* @author yidong.yang
* @date 2019-09-12
* @hitstory v2.0
*/
#include
#include
class CRC16Check : public QObject {
Q_OBJECT
public:
explicit CRC16Check(QObject *parent = nullptr);
unsigned short crc16Ccitt(unsigned char *puchMsg, unsigned int usDataLen);
unsigned short crc16CcittFalse(unsigned char *puchMsg, unsigned int usDataLen);///>本项目中使用的校验位
unsigned short crc16CcittFalseNew(unsigned char *puchMsg, unsigned int usDataLen);///>github代码
unsigned short crc16Xmodem(unsigned char *puchMsg, unsigned int usDataLen);
unsigned short crc16X25(unsigned char *puchMsg, unsigned int usDataLen);
unsigned short crc16Modbus(unsigned char *puchMsg, unsigned int usDataLen);
unsigned short crc16Ibm(unsigned char *puchMsg, unsigned int usDataLen);
unsigned short crc16Maxim(unsigned char *puchMsg, unsigned int usDataLen);
unsigned short crc16Usb(unsigned char *puchMsg, unsigned int usDataLen);
void invertUint8(unsigned char *dBuf, unsigned char *srcBuf);
void invertUint16(unsigned short *dBuf, unsigned short *srcBuf);
void invertUint32(unsigned int *dBuf, unsigned int *srcBuf);
uchar crcCUSUM(unsigned char *pBuffer, unsigned int dwLen);///>计算累加和
signals:
public slots:
};
#endif // CRC16CHECK_H
CPP
#include "crc16check.h"
CRC16Check::CRC16Check(QObject *parent) : QObject(parent) {
}
/**
* @brief 多项式x16+x12+x5+1(0x1021),
* 初始值0x0000,低位在前,高位在后,结果与0x0000异或
* @param puchMsg
* @param usDataLen
* @return
*/
unsigned short CRC16Check::crc16Ccitt(unsigned char *puchMsg, unsigned int usDataLen) {
unsigned short wCRCin = 0x0000;///>初始值
unsigned short wCPoly = 0x1021;///>多项式
unsigned char wChar = 0;
while (usDataLen--) {
wChar = *(puchMsg++);
invertUint8(&wChar, &wChar);
wCRCin ^= (wChar << 8);
for(int i = 0; i < 8; i++) {
if(wCRCin & 0x8000)
wCRCin = (wCRCin << 1) ^ wCPoly;
else
wCRCin = wCRCin << 1;
}
}
invertUint16(&wCRCin, &wCRCin);
return (wCRCin) ;
}
/**
* @brief 多项式x16+x12+x5+1(0x1021),
* 初始值0xFFFF,低位在后,高位在前,结果与0x0000异或
*
* @param puchMsg
* @param usDataLen
* @return
*/
unsigned short CRC16Check::crc16CcittFalse(unsigned char *puchMsg, unsigned int usDataLen) {
unsigned short wCRCin = 0xFFFF;///>初始值
unsigned short wCPoly = 0x1021;///>多项式x16+x12+x5+1
unsigned char wChar = 0;
// #pragma omp parallel for///>并行计算
// while (usDataLen--) {
for(int j = usDataLen; j > 0; j--) {
wChar = *(puchMsg++);
wCRCin ^= (wChar << 8);
for(int i = 0; i < 8; i++) {
if(wCRCin & 0x8000)
wCRCin = (wCRCin << 1) ^ wCPoly;
else
wCRCin = wCRCin << 1;
}
}
return (wCRCin) ;
}
/**
* @brief 2019-12-02新增
* @param puchMsg
* @param usDataLen
* @return
*/
unsigned short CRC16Check::crc16CcittFalseNew(unsigned char *puchMsg, unsigned int usDataLen) {
uint16_t crc = 0xFFFF;
for (uint32_t i = 0; i < usDataLen; i++) {
crc = (uint8_t)(crc >> 8) | (crc << 8);
crc ^= puchMsg[i];
crc ^= (uint8_t)(crc & 0xFF) >> 4;
crc ^= (crc << 8) << 4;
crc ^= ((crc & 0xFF) << 4) << 1;
}
return crc;
}
/**
* @brief 多项式x16+x12+x5+1(0x1021),
* 初始值0x0000,低位在后,高位在前,结果与0x0000异或
* @param puchMsg
* @param usDataLen
* @return
*/
unsigned short CRC16Check::crc16Xmodem(unsigned char *puchMsg, unsigned int usDataLen) {
unsigned short wCRCin = 0x0000;///>初始值
unsigned short wCPoly = 0x1021;///>多项式
unsigned char wChar = 0;
while (usDataLen--) {
wChar = *(puchMsg++);
wCRCin ^= (wChar << 8);
for(int i = 0; i < 8; i++) {
if(wCRCin & 0x8000)
wCRCin = (wCRCin << 1) ^ wCPoly;
else
wCRCin = wCRCin << 1;
}
}
return (wCRCin) ;
}
/**
* @brief 多项式x16+x12+x5+1(0x1021),
* 初始值0x0000,低位在前,高位在后,结果与0xFFFF异或
* @param puchMsg
* @param usDataLen
* @return
*/
unsigned short CRC16Check::crc16X25(unsigned char *puchMsg, unsigned int usDataLen) {
unsigned short wCRCin = 0xFFFF;
unsigned short wCPoly = 0x1021;
unsigned char wChar = 0;
while (usDataLen--) {
wChar = *(puchMsg++);
invertUint8(&wChar, &wChar);
wCRCin ^= (wChar << 8);
for(int i = 0; i < 8; i++) {
if(wCRCin & 0x8000)
wCRCin = (wCRCin << 1) ^ wCPoly;
else
wCRCin = wCRCin << 1;
}
}
invertUint16(&wCRCin, &wCRCin);
return (wCRCin ^ 0xFFFF) ;
}
/**
* @brief 多项式x16+x15+x5+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0x0000异或
* @param puchMsg
* @param usDataLen
* @return
*/
unsigned short CRC16Check::crc16Modbus(unsigned char *puchMsg, unsigned int usDataLen) {
unsigned short wCRCin = 0xFFFF;
unsigned short wCPoly = 0x8005;
unsigned char wChar = 0;
while (usDataLen--) {
wChar = *(puchMsg++);
invertUint8(&wChar, &wChar);
wCRCin ^= (wChar << 8);
for(int i = 0; i < 8; i++) {
if(wCRCin & 0x8000)
wCRCin = (wCRCin << 1) ^ wCPoly;
else
wCRCin = wCRCin << 1;
}
}
invertUint16(&wCRCin, &wCRCin);
return (wCRCin) ;
}
/**
* @brief 多项式x16+x15+x5+1(0x8005),初始值0x0000,低位在前,高位在后,结果与0x0000异或
* @param puchMsg
* @param usDataLen
* @return
*/
unsigned short CRC16Check::crc16Ibm(unsigned char *puchMsg, unsigned int usDataLen) {
unsigned short wCRCin = 0x0000;
unsigned short wCPoly = 0x8005;
unsigned char wChar = 0;
while (usDataLen--) {
wChar = *(puchMsg++);
invertUint8(&wChar, &wChar);
wCRCin ^= (wChar << 8);
for(int i = 0; i < 8; i++) {
if(wCRCin & 0x8000)
wCRCin = (wCRCin << 1) ^ wCPoly;
else
wCRCin = wCRCin << 1;
}
}
invertUint16(&wCRCin, &wCRCin);
return (wCRCin) ;
}
/**
* @brief 多项式x16+x15+x5+1(0x8005),初始值0x0000,低位在前,高位在后,结果与0xFFFF异或
* @param puchMsg
* @param usDataLen
* @return
*/
unsigned short CRC16Check::crc16Maxim(unsigned char *puchMsg, unsigned int usDataLen) {
unsigned short wCRCin = 0x0000;
unsigned short wCPoly = 0x8005;
unsigned char wChar = 0;
while (usDataLen--) {
wChar = *(puchMsg++);
invertUint8(&wChar, &wChar);
wCRCin ^= (wChar << 8);
for(int i = 0; i < 8; i++) {
if(wCRCin & 0x8000)
wCRCin = (wCRCin << 1) ^ wCPoly;
else
wCRCin = wCRCin << 1;
}
}
invertUint16(&wCRCin, &wCRCin);
return (wCRCin ^ 0xFFFF) ;
}
/**
* @brief 多项式x16+x15+x5+1(0x8005),初始值0xFFFF,低位在前,高位在后,结果与0xFFFF异或
* @param puchMsg
* @param usDataLen
* @return
*/
unsigned short CRC16Check::crc16Usb(unsigned char *puchMsg, unsigned int usDataLen) {
unsigned short wCRCin = 0xFFFF;
unsigned short wCPoly = 0x8005;
unsigned char wChar = 0;
while (usDataLen--) {
wChar = *(puchMsg++);
invertUint8(&wChar, &wChar);
wCRCin ^= (wChar << 8);
for(int i = 0; i < 8; i++) {
if(wCRCin & 0x8000)
wCRCin = (wCRCin << 1) ^ wCPoly;
else
wCRCin = wCRCin << 1;
}
}
invertUint16(&wCRCin, &wCRCin);
return (wCRCin ^ 0xFFFF) ;
}
/**
* @brief
*/
void CRC16Check::invertUint8(unsigned char *dBuf, unsigned char *srcBuf) {
int i;
unsigned char tmp[4];
tmp[0] = 0;
for(i = 0; i < 8; i++) {
if(srcBuf[0] & (1 << i))
tmp[0] |= 1 << (7 - i);
}
dBuf[0] = tmp[0];
}
void CRC16Check::invertUint16(unsigned short *dBuf, unsigned short *srcBuf) {
int i;
unsigned short tmp[4];
tmp[0] = 0;
for(i = 0; i < 16; i++) {
if(srcBuf[0] & (1 << i))
tmp[0] |= 1 << (15 - i);
}
dBuf[0] = tmp[0];
}
void CRC16Check::invertUint32(unsigned int *dBuf, unsigned int *srcBuf) {
int i;
unsigned int tmp[4];
tmp[0] = 0;
for(i = 0; i < 32; i++) {
if(srcBuf[0] & (1 << i))
tmp[0] |= 1 << (15 - i);
}
dBuf[0] = tmp[0];
}
/**
* @brief 计算累加和
* @param puchMsg
* @param usDataLen
*/
uchar CRC16Check::crcCUSUM(unsigned char *pBuffer, unsigned int dwLen) {
uchar sum_t = 0;
if(pBuffer == nullptr) {
return 0;
}
while(dwLen--) {
sum_t += *(char*)pBuffer++;
}
return sum_t;
}
测试
void UnitTesting::crcCheckTest() {
CRC16Check *crcCheck = new CRC16Check();
QByteArray testBytes;
testBytes.resize(6);
testBytes[0] = 0x01;
testBytes[1] = 0x02;
testBytes[2] = 0x03;
testBytes[3] = 0x04;
testBytes[4] = 0x05;
testBytes[5] = 0x06;
//读取dat文件,查看校验
/*
QFile aFile(QString("D:/code/QWA/QWA/QuickView2/debug/panorama_191018180903.dat")); //以文件方式读出
if (!(aFile.open(QIODevice::ReadOnly)))
return ;
QDataStream aStream(&aFile); //用文本流读取文件
// aStream.setVersion(QDataStream::Qt_5_9); //设置数据流的版本
aStream.setByteOrder(QDataStream::LittleEndian);
// aStream.setByteOrder(QDataStream::BigEndian);
char dataTemp[2026];
QByteArray testBytes;
testBytes.resize(2026);
qDebug() << aStream.readRawData((char *)&dataTemp, sizeof (char) * 2028);
memcpy(testBytes.data(), dataTemp, 2026);
*/
//结果为:十进制:50784 16进制:C6BA
qDebug() << "16-Ibm" << crcCheck->crc16Ibm((unsigned char*)testBytes.data(), static_cast(testBytes.size()));
//结果为:十进制:8773 16进制:2245
qDebug() << "16-usb" << crcCheck->crc16Usb((unsigned char*)testBytes.data(), static_cast(testBytes.size()));
//结果为:十进制:47118 16进制:B80E
qDebug() << "16-X25" << crcCheck->crc16X25((unsigned char*)testBytes.data(), static_cast(testBytes.size()));
//结果为:十进制:20353 16进制:4F81
qDebug() << "16-ccItt" << crcCheck->crc16Ccitt((unsigned char*)testBytes.data(), static_cast(testBytes.size()));
//结果为:十进制:14661 16进制:3945
qDebug() << "16-maxim" << crcCheck->crc16Maxim((unsigned char*)testBytes.data(), static_cast(testBytes.size()));
//结果为:十进制:56762 16进制:DDBA
qDebug() << "16-modebus" << crcCheck->crc16Modbus((unsigned char*)testBytes.data(), static_cast(testBytes.size()));
//结果为:十进制:55068 16进制:D71C
qDebug() << "16-CCittFalse" << crcCheck->crc16CcittFalse((unsigned char*)testBytes.data(), static_cast(testBytes.size()));
}
结果输出
在线校验输出是否正确