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. 【终极指南】使用Python可视化分析文本情感倾向

    本文分享自华为云社区<Python理解文本情感倾向的终极指南>,作者: 柠檬味拥抱. 情感分析是一种通过自然语言处理技术来识别.提取和量化文本中的情感倾向的方法.Python在这一领域有着 ...

  2. 揭秘华为如此多成功项目的产品关键——Charter模板

    很多推行IPD(集成产品开发)体系的公司在正式研发产品前,需要开发Charter,以确保产品研发方向的正确.Charter,即项目任务书或商业计划书.Charter的呈现标志着产品规划阶段的完成,能为 ...

  3. QGIS开发笔记(三):Windows安装版二次开发环境搭建(下):将QGis融入QtDemo,添加QGis并加载tif遥感图的Demo

    前言   使用QGis的目的是进行二次开发,或者说是融入我们的应用(无人车.无人船.无人机),本片描述搭建QGis二次基础开发环境,由于实在是太长了,进行了分篇: 上半部分:主要是安装好后,使用QtC ...

  4. 前端项目报EISDIR: illegal operation on a directory, read这个错误

    背景: 我用webstorm开发前端页面时,项目用Vue3来开发,出现如下报错. 原因: 这个报错是由于代码中引入的一些组件或者模块路径不正确导致的,在vue2中,引入组件是下面这样写的: impor ...

  5. Linux进程间通信-管道(pipe)

    本系列文章主要是学习记录Linux下进程间通信的方式. 常用的进程间通信方式:管道.FIFO.消息队列.信号量以及共享存储. 参考文档:<UNIX环境高级编程(第三版)> 参考视频:Lin ...

  6. 瑞数456vmp逆向分析

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 目标网站 aHR0cHM6 ...

  7. vue3 elementui plus Select 选择器不选择下拉框里面的数据得到的value值

    我们先来看 我点击弹框出现什么都不做 直接点击确定 看传参 tableId,timeColumnId,userColumnId直接是名称而没有获取value值 看下下拉框里面的数据 而我想直接点击获取 ...

  8. ABC340

    E 我们可以知道每一个点在每一轮加多少,具体如下: 假如现在操作的点的为 \(k\).那么所有的数都至少会加 \(\dfrac{A_k}{n}\).但是肯定有剩的,剩了 \(A_k \mod n\). ...

  9. C#.NET 国密 SM2 公钥证书从文本转换

    先前的 Util 是直接从文件中转换的 https://www.cnblogs.com/runliuv/p/15079404.html public static AsymmetricKeyParam ...

  10. sql去重常用的基本方法

    1.存在两条完全相同的纪录 select distinct * from table(表名) where (条件)   2.存在部分字段相同的纪录(有主键id即唯一键) 如果是这种情况的话用disti ...