1、CRC8 标准生成多项式

CRC-8   x8+x5+x4+1              0x31(0x131)
CRC-8   x8+x2+x1+1              0x07(0x107)
CRC-8   x8+x6+x4+x3+x2+x1       0x5E(0x15E)

注:由于多项式的最高为都为 1,并且在代码的 crc8 计算中,最高位也是不使用的,所以在多项式记录时都去掉了最高位。

2、 CRC 校验算法

原理:

把需要校验的数据与多项式进行循环异或(XOR),但进行 XOR 的方式与实际中数据传输时,与高位先传或低位先传有关。

对于数据高位先传的方式:

XOR 从数据的高位开始,称为顺序异或;

对于数据低位先传的方式:

XOR 从数据的低位开始,称为反序异或。

两种不同的异或方式,即使对应相同的多项式,计算出来的结果也是不一样的。

示例:

下面以顺序异或的例子说明一些计算的过程:

多项式:

x8+x5+x4+1(二进制为:100110001)

计算一个字节:

0x11(二进制为:00010001)

计算步骤:

A、因为采用顺序异或,所以需要计算的数据左移8位,移位后数据为:0001 0001 0000 000

B、先进行高9bit异或(多项式为9bit),0001 0001 0000 0000,因为高 9bit 的最高 bit 为 0,不需要进行异或,同理,接下来的两 bit 也是 0,也不需要进行进行异或。

这样处理后数据为:1 0001 0000 0000

C、接下来最高位为 1,需要进行异或操作了

从上面的计算过程可以看到,多项式最高位为1,遇到需要异或数据最高位为1时,才进行异或计算,并且异或后,最高位就为0了,最高位为0,下次也不需要异或了,

这样需要采用代码计算的方式,就可以把最高位去掉,不需要异或,最后结果也是一样的。

对于上面的计算过程,采用代码实现的方式如下:

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;
}

上面的代码是计算一个字节数据的crc结果,如果是计算多个字节的crc结果,也是比较简单;

先计算第一个字节的crc结果,然后把第一个字节的crc结果与第二个字节进行异或,异或后的值再进行一次crc计算就可以了,多个字节也是反复这过程就好。

如下为多个字节的crc校验代码:

unsigned char crc_high_first(unsigned char *ptr, unsigned char len)
{unsigned char i; unsigned char crc=0x00; /* 计算的初始crc值 */ while(len--){crc ^= *ptr++;  /* 每次先与需要计算的数据异或,计算完指向下一数据 */  for (i=8; i>0; --i)   /* 下面这段计算过程与计算一个字节crc一样 */  { if (crc & 0x80)crc = (crc << 1) ^ 0x31;elsecrc = (crc << 1);}}return (crc);
}

上面的crc计算是纯采用逻辑运行的方式,可以看到,需要的运行量也是不少的,每一个字节都需要进行8次判断、移位、或异或操作。

可以采用查表法,大大减少计算量,先计算出0x00~0xFF每一个字节的crc校验结果,后面就可以通过表来查出每个字节的crc结果,大大 减少计算量。

下面是一个表生成程序:

(生成表对应多项式:0x31(多项式:x8+x5+x4+1,100110001))

 void  create_crc_table(void){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
};

采用查表法计算crc代码如下:

unsigned char cal_crc_table(unsigned char *ptr, unsigned char len)
{unsigned char  crc = 0x00;while (len--){crc = crc_table[crc ^ *ptr++];}return (crc);
}

3、 反序异或的计算 

反序异或与顺序异或差异在数据先判断最低位,并且数据是向右移的,并且多项式数据位需要高低位反转一下。

多项式:

x8+x5+x4+1(二进制为:100110001)

则计算一个字节的 crc 校验代码如下:

unsigned char cal_table_low_first(unsigned char value)
{unsigned char i, crc;crc = value;/* 同样需要计算8次 */for (i=8; i>0; --i){ if (crc & 0x01)  /* 反序异或变成判断最低位是否为1 *//* 数据变成往右移位了 *//* 计算的多项式从0x31(0011 0001)变成了0x8C (1000 1100) *//* 多项式值,原来的最高位变成了最低位,原来的最低位变成最高位,8位数据高低位交换一下位置 */crc = (crc >> 1) ^ 0x8C;elsecrc = (crc >> 1);}return crc;
}

至于多个字节的crc校验及crc数据表的生成,只要把单个字节的计算方式替换一下顺序的 
计算方式。

所以,只要明确了crc校验使用的多项式,高位先校验还是低位先校验,计算crc的初始值是什么,那crc的计算就变得很简单了。

refer:

https://blog.csdn.net/zjli321/article/details/52998468

【Tool】CRC8 实现基础与原理解析相关推荐

  1. Android基础-LruCache原理解析

    一.Android中的缓存策略 一般来说,缓存策略主要包含缓存的添加.获取和删除这三类操作.如何添加和获取缓存这个比较好理解,那么为什么还要删除缓存呢?这是因为不管是内存缓存还是硬盘缓存,它们的缓存大 ...

  2. 【重识云原生】第六章容器基础6.4.5.3节——Deployment实现原理解析

    <重识云原生系列>专题索引: 第一章--不谋全局不足以谋一域 第二章计算第1节--计算虚拟化技术总述 第二章计算第2节--主流虚拟化技术之VMare ESXi 第二章计算第3节--主流虚拟 ...

  3. Java异常基础+原理解析+自定义异常

    Java异常基础+原理解析 1.什么是异常呀? 程序中的异常就好比人生病了,即再程序的运行过程中.出现非正常的情况,导致jvm非正常终止终止 异常的体系: 异常的的根类为java.lang.Throw ...

  4. java黄油刀_ButterKnife原理解析看这篇文章就够了

    原标题:ButterKnife原理解析看这篇文章就够了 作者:SheHuan https://juejin.im/post/5acec2b46fb9a028c6761628 ButterKnife 算 ...

  5. Tomcat 架构原理解析到架构设计借鉴

    ‍ 点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 Tomcat 架构原理解析到架构设计借鉴 Tomcat 发展这 ...

  6. 秋色园QBlog技术原理解析:性能优化篇:数据库文章表分表及分库减压方案(十五)...

    文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文件的作用 2: 秋色园QBlog技术原理解析:认识整站处理流程(二) --介绍秋色园业务处理流程 3: 秋色 ...

  7. CSS实现元素居中原理解析

    原文:CSS实现元素居中原理解析 在 CSS 中要设置元素水平垂直居中是一个非常常见的需求了.但就是这样一个从理论上来看似乎实现起来极其简单的,在实践中,它往往难住了很多人. 让元素水平居中相对比较简 ...

  8. spring配置文件中非bean标签的原理解析

    2019独角兽企业重金招聘Python工程师标准>>> 在spring配置文件中,我们经常见到context:property-placeholder/context:compone ...

  9. RocketMQ原理解析-producer 4.发送分布式事物消息

    2019独角兽企业重金招聘Python工程师标准>>> RocketMQ原理解析-producer 4.发送分布式事物消息 博客分类: MQ 为什么消息要具备事务能力 还是比较清晰的 ...

  10. Android 插件化原理解析——Activity生命周期管理

    之前的 Android插件化原理解析 系列文章揭开了Hook机制的神秘面纱,现在我们手握倚天屠龙,那么如何通过这种技术完成插件化方案呢?具体来说,插件中的Activity,Service等组件如何在A ...

最新文章

  1. Apache学习路线
  2. 学习官方示例 - System.Frac: 返回小数部分
  3. 基于eclipse RCP的文件夹管理工具
  4. Hadoop datanode正常启动,但是jps差不多datanode进程,而且Live nodes中却缺少节点
  5. python训练模型太大怎么处理_趣味Python之如何降低过拟合风险
  6. 高德地图+Serverless 护航你的假日出行
  7. 点聚weboffice php,点聚weboffice插件自定义菜单
  8. composer 设置代理
  9. 如何把静态成员导出_dll导入导出及local vftable问题
  10. 让css旋转字体图标
  11. 磨皮,美白,搞笑图片处理
  12. python点到直线的距离_点到直线距离公式的几种推导
  13. PG数据库内核分析学习笔记_XLOG日志恢复策略
  14. 修复WHS中缺少的外部硬盘数据库错误
  15. java public main_JAVA:public static void main(String args[]) 详解
  16. Jetson Nano、TX2等 conda 虚拟环境中使用TensorRT、gi等
  17. HDU 4411最小费用流
  18. 在Carla中加入可以使用的自己的车
  19. 如何一键实现计算机休眠
  20. 学习笔记——数据库(过滤搜索2:正则表达式)

热门文章

  1. node.js打包失败_与专家讨论Node.js-全部失败
  2. 利用百度图像识别鉴定植物
  3. FPGA数字信号处理(27)卷积编码器与Viterbi译码器设计
  4. 三维几何图形创作方法(Geometry3D)之二
  5. 电子计算机主机房国标,中华人民共和国国家标准电子计算机机房设计规范GB50174-93...
  6. 广域网、城域网及局域网技术
  7. Python3抓取糗百、不得姐
  8. ACdream - 1073 雷霆战机
  9. android手机免费无线投屏电脑方法教程步骤AirServer7
  10. php mysql购物系统_基于PHPMySQL 的网上购物系统设计与实现