#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <Windows.h>
#include <iostream>
using namespace std;
unsigned char crc8_chk_value(unsigned char *message, unsigned char len)
{
unsigned char crc;
unsigned char i;
crc = 0;
while (len--)
{
crc ^= *message++;
for (i = 0; i < 8; i++)
{
if (crc & 0x01)
{
crc = (crc >> 1) ^ 0x8c;
}
else crc >>= 1;
}
}
return crc;
}
//计算一串数据的8位CRC校验码,并将CRC校验值插入到数据尾部
//参数1:数据 参数2:数据字节长度 参数3:除数(最高位与最低位必须为1)
//(New,OK)
char* crc(char* p_src_data,int data_len, unsigned char divisor)
{
char* p_new_data = nullptr; //新数据
if (data_len <= 0 || p_src_data == nullptr || (divisor & 0x81) != 0x81)
goto err; //参数检查
p_new_data = new char[data_len + 2]; //为新数据分配内存,1字节为尾部插入的7位CRC校验码与0结尾字节
if (!p_new_data)
goto err;
ZeroMemory(p_new_data, data_len + 2);
//用于计算的位数,当超出就是计算完毕了,剩下的就是CRC校验码,7为加入计算的尾部+7位,
//-8代表第一次用于计算的8位
int max = ((data_len * 8) + 7) - 8;
int index = 0; //用于控制当前处理的字节索引
unsigned char result = 0; //CRC校验码
//先计算一次
result = p_src_data[0] ^ divisor;
result = (result << 1) | (p_src_data[((index / 8) + 1)] >> 7);
index += 1;
while (true)
{
if ((result >> 7) != 0)
{//商为1
result = result ^ divisor;
result = (result << 1) | ((p_src_data[(index / 8) + 1] >> (7 - index % 8)) & 0x01);
index += 1;
}
else
{//商为0
result = result ^ 0x00;
result = (result << 1) | ((p_src_data[(index / 8) + 1] >> (7 - index % 8)) & 0x01);
index += 1;
}
//结果
if (index >= max)
{
memcpy_s(p_new_data, data_len + 2, p_src_data, data_len);
result = result ^ divisor;
//插入
p_new_data[data_len] = (unsigned char)(result << 1);
break;
}
}
return p_new_data;
err:
if (p_new_data)
{
delete[]p_new_data;
p_new_data = nullptr;
}
return nullptr;
}
//利用尾部的CRC校验码,验证数据完整性
//参数1:携带8位CRC校验码的数据 参数2:数据长度(包括CRC字节) 参数3:与crc函数除数一样
bool crc_integrity(char* p_data, int data_len, unsigned char divisor)
{
if (data_len <= 0 || p_data == nullptr || (divisor & 0x81) != 0x81)
goto err; //参数检查
int max = (data_len * 8) - 1 - 8;
int index = 0; //用于控制当前处理的字节索引
unsigned char result = 0; //CRC校验码
//先计算一次
result = p_data[0] ^ divisor;
result = (result << 1) | (p_data[(index / 8) + 1] >> 7);
index += 1;
while (true)
{
if ((result >> 7) != 0)
{//商为1
result = result ^ divisor;
result = (result << 1) | ((p_data[(index / 8) + 1] >> (7 - index % 8)) & 0x01);
index += 1;
}
else
{//商为0
result = result ^ 0x00;
result = (result << 1) | ((p_data[(index / 8) + 1] >> (7 - index % 8)) & 0x01);
index += 1;
}
//结果
if (index >= max)
{
result = result ^ divisor;
if ((result & (~0x80)) == 0)
return true;
else
return false;
}
}
return false;
err:
return false;
}
int main()
{
char value[100] = { "B1" };
char* data = crc(value, strlen(value), 0xD1);
cout << endl;
bool isok = crc_integrity(data, strlen(data), 0xD1);
if (!isok)
{
DWORD err = 534;
}
delete[]data;
return 0;
//4e
}