crc 检验算法

CRC校验算法就是我们计网上所学的CRC冗余检验算法

一、CRC8校验算法

CRC8检验算法的标准生成多项式

1、标准生成多项式

CRC-8 x8+x5+x4+1 0x310x131CRC-8 x8+x2+x1+1 0x070x107CRC-8 x8+x6+x4+x3+x2+x1 0x5E0x15E//我们在实际的编程中最高位正好是用不到的

2、代码实现(标准算法)

#include <iostream> using namespace std; unsigned char En_CRC (unsigned char *ptr, unsigned char len) { unsigned char i; unsigned char crc=0x00; // 计算的初始crc值 while(len--) { crc ^= *ptr++; // 每次先与需要计算的数据异或,计算完指向下一数据 for (i=8; i>0; --i) //这就是大名鼎鼎的模2运算 { if (crc & 0x80) crc = (crc << 1) ^ 0x31; //CRC-8标准生成多项式 x8+x5+x4+1 0x31(0x131) else crc = (crc << 1); } } return (crc); } int main(){ unsigned char cip_crc[] = {0x11}; cout<<hex<<(int)En_CRC(cip_crc,1); return 0; }

3、代码实现(查表法)

//二、查表法 //首先计算0x00~0xFF每一个字节的crc校验结果 //然后查表 #include <iostream> using namespace std; unsigned char cal_table_high_first(unsigned char value) { unsigned char i, crc; crc = value; // 数据往左移了8位,需要计算8次 for (i=8; i>0; --i) { if (crc & 0x80) //判断最高位是否为1 { // 最高位为1,不需要异或,往左移一位,然后与0x31异或 // 0x31(多项式:x8+x5+x4+1,100110001),最高位不需要异或,直接去掉 crc = (crc << 1) ^ 0x31; } else { /// 最高位为0时,不需要异或,整体数据往左移一位 crc = (crc << 1); } } return crc; } void create_crc_table() { unsigned short i; unsigned char j; for (i=0; i<=0xFF; i++) { if (0 == (i%16)) printf("\n"); j = i&0xFF; printf("0x%.2x, ", cal_table_high_first (j)); //依次计算每个字节的crc校验值 } } //得到表格: static const unsigned char crc_table[] = { 0x00,0x31,0x62,0x53,0xc4,0xf5,0xa6,0x97,0xb9,0x88,0xdb,0xea,0x7d,0x4c,0x1f,0x2e, 0x43,0x72,0x21,0x10,0x87,0xb6,0xe5,0xd4,0xfa,0xcb,0x98,0xa9,0x3e,0x0f,0x5c,0x6d, 0x86,0xb7,0xe4,0xd5,0x42,0x73,0x20,0x11,0x3f,0x0e,0x5d,0x6c,0xfb,0xca,0x99,0xa8, 0xc5,0xf4,0xa7,0x96,0x01,0x30,0x63,0x52,0x7c,0x4d,0x1e,0x2f,0xb8,0x89,0xda,0xeb, 0x3d,0x0c,0x5f,0x6e,0xf9,0xc8,0x9b,0xaa,0x84,0xb5,0xe6,0xd7,0x40,0x71,0x22,0x13, 0x7e,0x4f,0x1c,0x2d,0xba,0x8b,0xd8,0xe9,0xc7,0xf6,0xa5,0x94,0x03,0x32,0x61,0x50, 0xbb,0x8a,0xd9,0xe8,0x7f,0x4e,0x1d,0x2c,0x02,0x33,0x60,0x51,0xc6,0xf7,0xa4,0x95, 0xf8,0xc9,0x9a,0xab,0x3c,0x0d,0x5e,0x6f,0x41,0x70,0x23,0x12,0x85,0xb4,0xe7,0xd6, 0x7a,0x4b,0x18,0x29,0xbe,0x8f,0xdc,0xed,0xc3,0xf2,0xa1,0x90,0x07,0x36,0x65,0x54, 0x39,0x08,0x5b,0x6a,0xfd,0xcc,0x9f,0xae,0x80,0xb1,0xe2,0xd3,0x44,0x75,0x26,0x17, 0xfc,0xcd,0x9e,0xaf,0x38,0x09,0x5a,0x6b,0x45,0x74,0x27,0x16,0x81,0xb0,0xe3,0xd2, 0xbf,0x8e,0xdd,0xec,0x7b,0x4a,0x19,0x28,0x06,0x37,0x64,0x55,0xc2,0xf3,0xa0,0x91, 0x47,0x76,0x25,0x14,0x83,0xb2,0xe1,0xd0,0xfe,0xcf,0x9c,0xad,0x3a,0x0b,0x58,0x69, 0x04,0x35,0x66,0x57,0xc0,0xf1,0xa2,0x93,0xbd,0x8c,0xdf,0xee,0x79,0x48,0x1b,0x2a, 0xc1,0xf0,0xa3,0x92,0x05,0x34,0x67,0x56,0x78,0x49,0x1a,0x2b,0xbc,0x8d,0xde,0xef, 0x82,0xb3,0xe0,0xd1,0x46,0x77,0x24,0x15,0x3b,0x0a,0x59,0x68,0xff,0xce,0x9d,0xac }; //查表 unsigned char cal_crc_table(unsigned char *ptr, unsigned char len) { unsigned char crc = 0x00; while (len--) { crc = crc_table[crc ^ *ptr++]; } return (crc); } int main(){ create_crc_table(); unsigned char cip_crc[] = {0x11}; cout<<endl; cout<<hex<<(int)cal_crc_table(cip_crc,1)<<endl; return 0; }

二、CRC32

CRC32和CRC8原理几乎一致,这里直接给出代码
代码实现(查表法)(顺序表)
#include <inttypes.h> #include <stdio.h> #include <string.h> uint32_t rc_crc32(uint32_t crc, const char *buf, size_t len) { static uint32_t table[256]; static int have_table = 0; uint32_t rem; uint8_t octet; int i, j; const char *p, *q; /* This check is not thread safe; there is no mutex. */ if (have_table == 0) { /* Calculate CRC table. */ for (i = 0; i < 256; i++) { rem = i; /* remainder from polynomial division */ for (j = 0; j < 8; j++) { if (rem & 1) { //本来是要给buff[i]补24个0,然后rem & 0x80000000 的,但实际编程发现,这两个正好可以省去// rem >>= 1; rem ^= 0xedb88320; } else rem >>= 1; } table[i] = rem; } have_table = 1; } crc = ~crc; //这个数据。。。赋值为 0xffffffff //主要是为了满足32位 q = buf + len; for (p = buf; p < q; p++) { octet = *p; /* Cast to unsigned octet. */ crc = (crc >> 8) ^ table[(crc & 0xff) ^ octet]; //右移8位的目的是一个字符一个字符的迭代 } return ~crc; //正序的顺序表结果别忘取逆反 } int main() { const char *s = "1"; printf("%p\n", rc_crc32(0, s, strlen(s))); return 0; }

 

参考链接:

 

__EOF__

本文作者_TLSN
本文链接https://www.cnblogs.com/lordtianqiyi/articles/16471256.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   TLSN  阅读(447)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示