CRC校验

这边直接上代码了,一些学习理论都是网上有哦!下面也有给出连接

#include <iostream>

using namespace std;


void crc32_ccitt(unsigned long data, unsigned long& crc);
unsigned long crc32_tticc(unsigned long data, unsigned long crc);

/*
* CRC校验Demo
* 原理学习网站:https://blog.51cto.com/winda/1063951
* 代码参考网站:https://www.cnblogs.com/wchonline/p/11698677.html
* 参考网站有部分存在错误,函数中有个变量写的不对
* unsigned short ccitt16 = 0x1021; 应该是0x11021
*/

int main()
{
	//data表示文件大小,res是获取的校验码
	unsigned long data = 0xffff, res = 0;
	cout << "data = " << data << endl;
	//计算CRC校验码
	crc32_ccitt(data, res);
	cout << "res = " << res << endl;
	unsigned long ret = 0;  //验算结果  不为0表示失败
	//验算CRC校验码
	ret = crc32_tticc(data, res);
	if (ret == 0)
	{
		cout << "success" << endl;
	}
	else
	{
		cout << "error" << endl;
	}
	return 0;
}


/*
* 函数名:void crc16_ccitt(unsigned long data, unsigned long& crc)
* 函数参数:data:文件大小;crc:获取的CRC校验码
* 函数功能:获取CRC校验码
* 函数返回值:void
*/
void crc32_ccitt(unsigned long data, unsigned long& crc)
{
	//CRC16最多效验0xff以内的数据,超过后会不正常
	unsigned long citt16 = 0x104C11DB7;  //正序
	int i;

	crc ^= (data << 16);
	for (i = 0; i < 16; i++)
	{
		if (crc & 0x80000000)
		{
			//这里表示res的位数和citt16一样
			//先进行移位,保证和citt的位数一样
			//位数一样才可以进行与非
			crc <<= 1;
			crc ^= citt16;
		}
		else
		{
			crc <<= 1;
		}
	}
}


/*
* 函数名:unsigned long crc16_tticc(unsigned long data, unsigned long crc)
* 函数参数:data:文件大小;crc:CRC校验码
* 函数功能:验证文件大小是否正确
* 函数返回值:unsigned long   0—效验成功   非0—效验失败,文件大小不对
*/
unsigned long crc32_tticc(unsigned long data, unsigned long crc)
{
	unsigned long res = (data << 16) + (crc >> 16);
	unsigned long citt16 = 0x104C11DB7;  //正序
	crc &= 0x0000ffff;  //去掉crc的高16位
	for (int i = 0; i < 16; i++)
	{
		if (res & 0x80000000)
		{
			//这里表示res的位数和citt16一样
			//先进行移位,保证和citt的位数一样
			//位数一样才可以进行与非
			res <<= 1;
			res += (crc >> 15 - i); //取出crc的最高位
			crc &= (0x00007fff >> i);  //crc的最高位取出后要移除
			res ^= citt16;
		}
		else
		{
			res <<= 1;
			res += (crc >> 15 - i);
			crc &= (0x00007fff >> i);
		}
	}
	return res;
}

上一篇:CRC总结-2


下一篇:C++ 解析 TFRecord 文件 using Protocal Buffer