CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。

CRC校验可以简单地描述为:例如我们要发送一些数据(信息字段),为了避免一些干扰以及在接收端的对读取的数据进行判断是否接受的是真实的数据,这时我们就要加上校验数据(即CRC校验码),来判断接收的数据是否正确。在发送端,根据要传送的k位二进制码序列,以一定的规则(CRC校验有不同的规则。这个规则,在差错控制理论中称为“生成多项式”。)产生一个校验用的r位校验码(CRC码),附在原始信息后边,构成一个新的二进制码序列数共k+r位,然后发送出去。在接收端,根据信息码和CRC码之间所遵循的规则(即与发送时生成CRC校验码相同的规则)进行检验,校验采用计算机的模二除法,即除数和被除数(即生成多项式)做异或运算,进行异或运算时除数和被除数最高位对齐,进行按位异或运算,若最终的数据能被除尽,则传输正确;否则,传输错误。

CRC8即最终生成的CRC校验码为1字节,其生成多项式,生成多项式为g(x)=x8+x5+x4+1,相当于g(x)=1·x8+0·x7+0·x6+1·x5+1·x4+0·x3+0·x2+0·x1+1·x0,即对应的二进制数为100110001。

CRC8校验算法:

1.CRC8校验的一般性算法:

例如:  信息字段代码为: 00000001 00000010         ————    对应m(x)=x8+x

生成多项式为:g(x)=x8+x5+x4+1                 ————    对应g(x)的二进制代码为:100110001

现在我们将要对2字节数据0x0102生成CRC8校验码,并最终将生成的1字节CRC校验码跟在0x0102的后面,即 0x01 02 ##,(##即8为CRC码),最终生成的3字节数据就是经CRC8校验生成的数据。

先计算x8m(x)=x16+x9,对应的2进制数为:100000010 00000000  。可以看到这样运算所得到的结果其实就是将信息字段代码的数左移8位。因为最终要将生成的8位CRC8校验码附在信息字段的后面,所以要将信息字段的数左移8位。最后用x8m(x)得到的二进制数对生成多项式g(x)进行模二运算,最终的余数(其二进制数的位数一定比生成多项式g(x)的位数小)就是所要的CRC8校验码。

(差与被除数高位对齐)

100000010 00000000

^ 100110001

---------------------------

000110011 00000000

^      100110 001

---------------------------

010101  00100000

^          10011 0001

---------------------------

00110 00110000

^           100 110001

---------------------------

010 11110100

^            10 0110001

---------------------------

00 10010110

对x8m(x)做模二运算取余得10010110(0x96),这个8位的二进制数就是CRC8校验码。所以,经CRC8校验后研发送的数据就是0x010296。

for (_bit = 8; _bit > 0; --_bit)
  { 
     if (crc & 0x80) 
     {
       crc = (crc << 1) ^ 0x0131;(所有多项式的最高位都为1,所以左移1位)
     }
      else
      {
       crc = (crc << 1);
      }
  }

CRC examples 
 
The input message 11011100 (0xDC) will have as result 01111001 (0x79). 
 
The input message 01101000 00111010 () will have as result 01111100 (0x7C). 
 
The input message 01001110 10000101 () will have as result 01101011 (0x6B).

2.CRC8校验在DS18B20中的应用:

以上分析的是常规的CRC8校验方法。在DS18B20中,有两处用到CRC。一是DS18B20的8字节的序列号,最后一字节是前面七个字节的CRC码,这是为了保证序列号的唯一性与正确性;另一个是在DS18B20内部9字节的高速温度存储器,其第9字节是前面8个字节的CRC校验码,这是为了温度数据传输的正确性。而在DS18B20中生成CRC码所用到的方法不同于常规生成算法,它采用的是逆序CRC信息单元编码算法,该CRC的生成是由DS18B20中的多项式寄存器通过其中所包含的移位寄存器以及异或门对输入该多项式寄存器的每一位二进制数做一定的运算所得到的CRC码(可以查看Maxim官网上DS18B20的应用笔记Note27,专门介绍DS18B20CRC详细生成过程)。在此列举两种DS18B20CRC校验的C程序。

      A.按位运算方法
1.  /********************************************************/  
2.     /*DS18B20的CRC8校验程序*/  
3.     /********************************************************/   
4.     uchar calcrc_1byte(uchar abyte)   
5.     {   
6.        uchar i,crc_1byte;     
7.        crc_1byte=0;                //设定crc_1byte初值为0  
8.        for(i = 0; i < 8; i++)   
9.         {   
10.       if(((crc_1byte^abyte)&0x01))   
11.          {   
12.            crc_1byte^=0x18;     
13.            crc_1byte>>=1;   
14.            crc_1byte|=0x80;   
15.           }         
16.        else     
17.           crc_1byte>>=1;   
18.        abyte>>=1;         
19.      }   
20.      return crc_1byte;   
21. }   
22. uchar calcrc_bytes(uchar *p,uchar len)  
23. {  
24.  uchar crc=0;  
25.  while(len--) //len为总共要校验的字节数  
26.   {  
27.     crc=calcrc_1byte(crc^*p++);  
28.   }  
29.  return crc;  //若最终返回的crc为0,则数据传输正确  
30. }  
 
      B.查表法
        unsigned char crc_array[256] = {
                                                    0x00, 0x5e, 0xbc, 0xe2, 0x61, 0x3f, 0xdd, 0x83,
                                                    0xc2, 0x9c, 0x7e, 0x20, 0xa3, 0xfd, 0x1f, 0x41, 
                                                    0x9d, 0xc3, 0x21, 0x7f, 0xfc, 0xa2, 0x40, 0x1e,
                                                    0x5f, 0x01, 0xe3, 0xbd, 0x3e, 0x60, 0x82, 0xdc, 
                                                    0x23, 0x7d, 0x9f, 0xc1, 0x42, 0x1c, 0xfe, 0xa0,
                                                    0xe1, 0xbf, 0x5d, 0x03, 0x80, 0xde, 0x3c, 0x62, 
                                                    0xbe, 0xe0, 0x02, 0x5c, 0xdf, 0x81, 0x63, 0x3d,
                                                    0x7c, 0x22, 0xc0, 0x9e, 0x1d, 0x43, 0xa1, 0xff,
                                                    0x46, 0x18, 0xfa, 0xa4, 0x27, 0x79, 0x9b, 0xc5, 
                                                    0x84, 0xda, 0x38, 0x66, 0xe5, 0xbb, 0x59, 0x07,
                                                    0xdb, 0x85, 0x67, 0x39, 0xba, 0xe4, 0x06, 0x58,
                                                    0x19, 0x47, 0xa5, 0xfb, 0x78, 0x26, 0xc4, 0x9a,
                                                    0x65, 0x3b, 0xd9, 0x87, 0x04, 0x5a, 0xb8, 0xe6, 
                                                    0xa7, 0xf9, 0x1b, 0x45, 0xc6, 0x98, 0x7a, 0x24, 
                                                    0xf8, 0xa6, 0x44, 0x1a, 0x99, 0xc7, 0x25, 0x7b,
                                                    0x3a, 0x64, 0x86, 0xd8, 0x5b, 0x05, 0xe7, 0xb9, 
                                                    0x8c, 0xd2, 0x30, 0x6e, 0xed, 0xb3, 0x51, 0x0f, 
                                                    0x4e, 0x10, 0xf2, 0xac, 0x2f, 0x71, 0x93, 0xcd,
                                                    0x11, 0x4f, 0xad, 0xf3, 0x70, 0x2e, 0xcc, 0x92,
                                                    0xd3, 0x8d, 0x6f, 0x31, 0xb2, 0xec, 0x0e, 0x50, 
                                                    0xaf, 0xf1, 0x13, 0x4d, 0xce, 0x90, 0x72, 0x2c, 
                                                    0x6d, 0x33, 0xd1, 0x8f, 0x0c, 0x52, 0xb0, 0xee, 
                                                    0x32, 0x6c, 0x8e, 0xd0, 0x53, 0x0d, 0xef, 0xb1, 
                                                    0xf0, 0xae, 0x4c, 0x12, 0x91, 0xcf, 0x2d, 0x73, 
                                                    0xca, 0x94, 0x76, 0x28, 0xab, 0xf5, 0x17, 0x49,
                                                    0x08, 0x56, 0xb4, 0xea, 0x69, 0x37, 0xd5, 0x8b,
                                                    0x57, 0x09, 0xeb, 0xb5, 0x36, 0x68, 0x8a, 0xd4,
                                                    0x95, 0xcb, 0x29, 0x77, 0xf4, 0xaa, 0x48, 0x16, 
                                                    0xe9, 0xb7, 0x55, 0x0b, 0x88, 0xd6, 0x34, 0x6a, 
                                                    0x2b, 0x75, 0x97, 0xc9, 0x4a, 0x14, 0xf6, 0xa8, 
                                                    0x74, 0x2a, 0xc8, 0x96, 0x15, 0x4b, 0xa9, 0xf7,
                                                    0xb6, 0xe8, 0x0a, 0x54, 0xd7, 0x89, 0x6b, 0x35,
                                                    };
            unsigned char CRC8_Table(unsigned char *p, char counter)
            {
               unsigned char crc8 = 0;
               for( ; counter > 0; counter--)
                {
                   crc8 = CRC8Table[crc8^*p]; //查表得到CRC码
                   p++;
                }
              return crc8;
            }
       DS18B20的两种校验CRC码的方法本质上都是一样的。查表法是对0x00~0xff这256个数依次生成与每一个数对应的CRC码所组合成的表,每次算一字节数据的CRC码不用经过calcrc_1byte(uchar abyte)这个函数对每个数据的最低位进行判断是1还是0,而直接通过查表的方式直接提取出  crc8^*p的CRC码,其运行效率相对按位运算方法更高,但是查表法所列的表却很占空间。  
 
https://www.maximintegrated.com/cn/design/technical-documents/app-notes/2/27.html官方文章

18B20的CRC8校验分析的更多相关文章

  1. Android5.1.1 - APK签名校验分析和修改源码绕过签名校验

    Android5.1.1 - APK签名校验分析和修改源码绕过签名校验 作者:寻禹@阿里聚安全 APK签名校验分析 找到PackageParser类,该类在文件“frameworks/base/cor ...

  2. CRC8校验

    static u8 crccheck(u8* p,u8 len) //CRC校验,返回CRC检验值 { u8 bit0,cbit,i,j,byte,temp; temp = ; ; j < le ...

  3. Java获取字符串的CRC8校验码(由C程序的代码修改为了Java代码)

    CRC8算法请百度,我也不懂,这里只是把自己运行成功的结构贴出来了.方法CRC8_Tab这里没有处理,因为我的程序中没有用到. package com.crc; public class CCRC8_ ...

  4. Samp免流软件以及地铁跑酷的自校验分析

    [文章标题]:Samp免流软件以及地铁跑酷的自校验分析 [文章作者]: Ericky [作者博客]: http://blog.csdn.net/hk9259 [下载地址]: 自行百度 [保护方式]: ...

  5. CRC8反转校验

    最近在做项目遇到一个问题,就是需要对数据进行CRC8校验,多项式是 X7+X6+X5+X2+1,对应的二进制表达是 11100101,但是因为传输反转所以我们这里的多项式二进制表达方式 为 10100 ...

  6. Hadoop IO 特性详解(2)【文件校验】

    (本文引用了microheart,ggjucheng的一些资料,在此感谢.charles觉得知识无价,开源共享无价) 这一次我们接着分析文件IO校验的相关代码,看看最底层是如何实现这种大数据集的文件校 ...

  7. 【深入Java虚拟机】之四:类加载机制

    类加载过程     类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段.它们开始的顺序如下图所示: 其中类加载的过程包括了加载.验 ...

  8. Storm中遇到的日志多次重写问题(一)

    业务描述: 统计从kafka spout中读取的数据条数,以及写入redis的数据的条数,写入hdfs的数据条数,写入kafaka的数据条数.并且每过5秒将数据按照json文件的形式写入日志.其中保存 ...

  9. Android安全开发之通用签名风险

    Android安全开发之通用签名风险 作者:伊樵.舟海.呆狐@阿里聚安全 1 通用签名风险简介 1.1 Android应用签名机制 阿里聚安全漏洞扫描器有一项检测服务是检测APP的通用签名风险.And ...

  10. JVM学习笔记:虚拟机的类加载机制

    JVM类加载机制分两部分来总结: (1)类加载过程 (2)类加载器 一.JVM类加载过程 类的加载过程:加载 →连接(验证 → 准备 → 解析)→ 初始化. 类的生命周期:加载 →连接(验证 → 准备 ...

随机推荐

  1. 23ai中的True Cache到底能做啥?

    最近,Oracle的产品管理总监在Oracle数据库内幕中介绍了True Cache. 原文链接如下: https://blogs.oracle.com/database/post/introduci ...

  2. Swift 排查引用循环

    ------------恢复内容开始------------ 一.最近使用RxSwift在多次信号的嵌套中,发现一个对象始终始终无法释放 开始想通过Memory Graph验证是否没有释放,一直报错, ...

  3. Linux Topicons Plus桌面工具安装

    Topicons Plus是Linux系统GNOME桌面环境的工具,方便于在工具栏显示应用小图标. 1.进入GNOME商店搜搜下载TopIcons Plus工具.下载路径:https://extens ...

  4. 喜讯!INFINI Easysearch 在墨天轮数据库排名中挺进前30!

    近日,2023 年 10 月的 墨天轮中国数据库流行度排行 火热出炉,本月共有 283 个数据库参与排名,中国数据库行业竞争日益激烈.其中,极限科技旗下软件产品 INFINI Easysearch 稳 ...

  5. C#.NET Framework 使用BC库(BouncyCastle) RSA 私钥签名 公钥验签(验证签名) ver:20230704

    C#.NET Framework 使用BC库(BouncyCastle) RSA 私钥签名 公钥验签(验证签名) ver:20230704 环境说明: .NET Framework 4.6 的控制台程 ...

  6. centos 7 mysql8 安装和卸载

    cent os 7 安装 mysql 8--install-start官网下载MySQL的RPM源,地址:https://dev.mysql.com/downloads/repo/yum/ 下载这个项 ...

  7. rust 程序设计笔记(1)

    简介 - Rust 程序设计语言 简体中文版 hello world & rust相关工具使用 hello world rustc rustc --version complie .rs pr ...

  8. FreeRTOS简单内核实现6 优先级

    0.思考与回答 0.1.思考一 如何实现 RTOS 内核支持多优先级? 因为不支持优先级,所以所有的任务都插入了一个名为 pxReadyTasksLists 的就绪链表中,相当于所有任务的优先级都是一 ...

  9. PhantomReference 和 WeakReference 究竟有何不同

    本文基于 OpenJDK17 进行讨论,垃圾回收器为 ZGC. 提示: 为了方便大家索引,特将在上篇文章 <以 ZGC 为例,谈一谈 JVM 是如何实现 Reference 语义的> 中讨 ...

  10. STM32的内存管理(转)

    背景 这里针对STM32F407芯片+1M外部内存的内存管理!(全篇是个人愚见,如果错误,请不吝指出!) 定义 首先,定义3个内存池,分别是内部SRAM,外表SRAM和CCM:通过指定内存中的绝对地址 ...