Qt crc16校验位计算

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()));
}
结果输出

Qt crc16校验位计算_第1张图片

在线校验输出是否正确

你可能感兴趣的:(qt)