CRC校验算法详解

这篇具有很好参考价值的文章主要介绍了CRC校验算法详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、关于CRC的介绍

        数据在传输过程(比如通过网线在两台计算机间传文件)中,由于传输信道的原因,可能会有误码现象(比如说发送数字5但接收方收到的却是6),方法发送额外的数据让接收方校验是否正确,这就是数据校验。常用的校验方法是和校验,就是将传送的数据(按字节方式)加起来计算出数据的总和,并将总和传给接收方,接收方收到数据后也计算总和,并与收到的总和比较看是否相同。如果传输中出现误码,那么总和一般不会相同,从而知道有误码产生,可以让发送方再发送一遍数据。

        CRC即循环冗余校验码(Cyclic Redundancy Check):数据通信领域中最常用的一种差错校验码,其信息字段和校验字段长度可以任意指定,但要求通信双方定义的CRC标准一致。

二、工作原理

1.CRC原理

        在K位信息码(目标发送数据)后再拼接R位校验码,使整个编码长度为N位,因此这种编码也叫(N,K)码。通俗的说,就是在需要发送的信息后面附加一个数(即校验码),生成一个新的发送数据发送给接收端。这个数据要求能够使生成的新数据被一个特定的数整除。这里的整除需要引入模 2除法的概念,CRC校验的过程

(1)选定一个标准除数(K位二进制数据串)

(2)在要发送的数据(m位)后面加上K-1位0,然后将这个新数(M+K-1位)以模2除法的方式除以上面这个标准除数,所得到的余数也就是该数据的CRC校验码(注:余数必须比除数少且只少一位,不够就补0)

(3)将这个校验码附在原m位数据后面,构成新的M+K-1位数据,发送给接收端。

(4)接收端将接收到的数据除以标准除数,如果余数为0则认为数据正确。

        注意:CRC校验中有两个关键点:一是要预先确定一个发送端和接收端都用来作为除数的二进制比特串(或多项式);二是把原始帧与上面选定的除进行二进制除法运算,计算出FCS。前者可以随机选择,也可按国际上通行的标准选择,但最高位和最低位必须均为“1”

实例:对于数据10110011(16#B3),以指定除数110011求它的CRC校验码,其过程如下:

2.CRC校验码的计算

        这里需要知道几个组成部分或者说计算概念:多项式公式、多项式简记式、数据宽度、初始值、结果异或值、输入值反转、输出值反转、参数模型。

(1)多项式公式

        对于CRC标准除数,一般使用多项式(或二项式)公式表示,如上例中除数11011的二项式为G(X)=X4+X3+X+1,X的指数就代表了该bit位上的数据为1,(最低位为0)。这里特别注意一下位数问题,除数的位数为二项式最高次幂+1(4+1=5),这个很重要。

(2)多项式简记式

        通过对CRC的基本了解我们知道,多项式的首尾必定为1,而这个1的位置在下一步计算一定为0,所以就把前面这个1给省略掉了,出现了一个叫简记式的东西,如上例中除数11011的简记式为1011,很多看过CRC高级语言源码的人会知道,对于CRC_16标准下G(X)=X16+X15+X2+1(16#18005)的poly值实际上是8005,这里使用的就是简记式。后面会对这个用法做一个说明。

(3)数据宽度

        数据宽度指的就是CRC校验码的长度(二进制位数),知道了CRC的运算概念和多项式,就可以理解这个概念了,CRC长度始终要比除数位数少1,与简记式长度是一致的。

        以上三个数据就是我们经常能够用到的基本数据

(4)初始值与结果异或值

        在一些标准中,规定了初始值,则数据在进行上述二项式运算之前,需要先将要计算的数据与初始值的最低字节进行异或,然后再与多项式进行计算。

        而在结果异或值不为零的情况下,则需要将计算得到的CRC结果值再与结果异或值进行一次异或计算,得到的最终值才是我们需要的CRC校验码。

这里可以看出,初始值与结果值的位数要求与数据宽度一致。

(5)输入值反转与输出值反转

        输入值反转的意思是在计算之前先将二项式反转,然后再用得到的新值和数据进行计算。如对于G(X)=X16+X15+X2+1(16#18005),其正向值为1 1000 0000 0000 0101,反转值则为1010 0000 0000 0001 1

        输出值反转则是将最终得到的CRC结果反转。

        通常,输入值反转后的结果值也会是反转的,所以这两个选项一般是同向的,我们只有在在线CRC计算器中会看到自由选择正反转的情况存在。

三、实现代码

1.	package CRC;    
2.	    
3.	    
4.	public class CRC12 {    
5.	        
6.	    public static String resultBinaryCRC=null;   //crc用二进制表示    
7.	    public static String messageBinary=null;     //结果用二进制表示    
8.	    public static String messageOct=null;        //结果用十进制表示    
9.	    public static int a = 0x180f;                 // 生成多项式    
10.	    public static int CRCBIT = 12;    
11.	    
12.	    public static void  main(String [] args){    
13.	        String message="2";    
14.	        CRC12 a=new CRC12();    
15.	        a.doCalculate(message);    
16.	    
17.	    }    
18.	        
19.	    public   void doCalculate(String Num)     
20.	    {    
21.	        String crcTemp = null;//余数    
22.	        Boolean flag = true;    
23.	        int number = Integer.valueOf(Num); // 发送的数据的十进制表示    
24.	        int nextNumber = number << CRCBIT; // 变成了被除数    
25.	        int NumberMinus = Integer.toBinaryString(nextNumber).length()- Integer.toBinaryString(a).length();// 找出被除数比除数多几个0    
26.	    
27.	        int nextNumberString12 = nextNumber >> NumberMinus; // 得到前13位的数值    
28.	        // 前13位与除数做异或运算    
29.	        while (NumberMinus >=0)     
30.	        {     
31.	            if (flag == true)  //设置boolean目的是保证只运行一次代码    
32.	            {    
33.	                crcTemp = Integer.toBinaryString(nextNumberString12);    
34.	                flag = false;    
35.	            }    
36.	    
37.	            if (crcTemp.length() == 13)  //余数补0,直到凑齐13位,然后再与生成多项式模2运算    
38.	            {    
39.	    
40.	                    nextNumberString12 = Integer.parseInt(crcTemp, 2) ^ a; // 余数与生成多项式异或运算    
41.	                    crcTemp = Integer.toBinaryString(nextNumberString12); // 将余数变成二进制表示    
42.	            }    
43.	                
44.	            if(NumberMinus>0)    
45.	            {crcTemp = crcTemp + "0";}    
46.	            NumberMinus--;    
47.	                
48.	        }    
49.	            
50.	        int k=12-crcTemp.length();   //根据余数的位数,补0变成12位    
51.	        StringBuilder resultCrc=new StringBuilder();                 //创建最终结果的StringBuilder    
52.	        resultCrc.append(Integer.toBinaryString(Integer.parseInt(Num)));    
53.	        for(int i=0;i<k;i++) //余数不足12位,要补前导0,补齐12位    
54.	        {    
55.	            resultCrc.append("0");    
56.	        }    
57.	        resultCrc.append(crcTemp);    
58.	        setMessageBinary(resultCrc.toString());    
59.	        setResultBinaryCRC(crcTemp);    
60.	        int temp=Integer.parseInt(messageBinary,2);   //二进制变成十进制表示    
61.	        String aaa=Integer.toHexString(temp);    
62.	        setMessageOct(aaa);    
63.	            
64.	            
65.	        System.out.println("你发送的数据十进制表示"+Num);    
66.	        System.out.println("你发送的数据二进制表示"+Integer.toBinaryString(number));    
67.	        System.out.println("校验码"+this.getResultBinaryCRC());    
68.	        System.out.println("最终发送数据二进制表示是"+this.getMessageBinary());    
69.	        System.out.println("最终发送数据十进制表示是"+this.getMessageOct());    
70.	    
71.	    }    
72.	    
73.	    public  String getResultBinaryCRC() {    
74.	        return resultBinaryCRC;    
75.	    }    
76.	    
77.	    public  void setResultBinaryCRC(String resultBinaryCRC) {    
78.	        CRC12.resultBinaryCRC = resultBinaryCRC;    
79.	    }    
80.	    
81.	    public  String getMessageBinary() {    
82.	        return messageBinary;    
83.	    }    
84.	    
85.	    public  void setMessageBinary(String messageBinary) {    
86.	        CRC12.messageBinary = messageBinary;    
87.	    }    
88.	    
89.	    public  String getMessageOct() {    
90.	        return messageOct;    
91.	    }    
92.	    
93.	    public  void setMessageOct(String messageOct) {    
94.	        CRC12.messageOct = messageOct;    
95.	    }    
96.	}    

 文章来源地址https://www.toymoban.com/news/detail-704392.html

到了这里,关于CRC校验算法详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 循环冗余校验(CRC)的计算

    循环冗余校验(CRC)的计算

    循环冗余校验(Cyclic Redundancy Check,CRC)是一种根据网络数据包或电脑文件等数据产生简短固定位数校验码的一种散列函数,主要用来检测或校验数据传输或者保存后可能出现的错误。它是利用除法及余数的原理来作错误侦测的。 若信息码字为111000110,生成多项式 x 5 x^5 x 5 + x

    2024年02月11日
    浏览(7)
  • c# 如何编写CRC校验算法

    在C#中编写CRC校验算法,可以使用以下步骤: 首先需要确定CRC校验的多项式和初始值。根据具体的需求和应用场景,选择合适的CRC多项式和初始值。 定义一个计算CRC校验值的函数,函数的输入参数为待校验数据的字节数组,输出参数为计算得到的CRC校验值。 在函数中,先对

    2024年02月13日
    浏览(9)
  • 16位CRC校验码计算,485MODBUS计算

    CRC计算方法是: 1、 加载一值为0XFFFF的16位寄存器,此寄存器为CRC寄存器。 2、 把第一个8位二进制数据(即通讯信息帧的第一个字节)与16位的CRC寄存器的相异或,异或的结果仍存放于该CRC寄存器中。 3、 把CRC寄存器的内容右移一位,用0填补最高位,并检测移出位是0还是1。

    2024年02月11日
    浏览(10)
  • CRC校验码详解+Verilog实现(含代码)

    CRC校验码详解+Verilog实现(含代码)

    目录 CRC码简介 CRC校验码生成步骤  CRC码生成多项式  CRC校验码Verilog实现 CRC即循环冗余校验,是一种数字通信中的常用信道编码技术。其特征是信息段和校验字段的长度可以任意选定 CRC码是由2部分组成的,前部分是信息码,后部分是校验码,如果CRC码长共 n bit,信息码长

    2023年04月08日
    浏览(9)
  • MODBUS RTU 通信协议 CRC16校验算法

    MODBUS RTU 通信协议 CRC16校验算法

    CRC校验码是一个2个字节(16位二进制)的数。 发送端:发送的数据计算CRC校验码----发送:数据+CRC校验码 接收端:收到数据后重新计算CRC校验码,然后和接收到数据中的CRC校验码进行比较,判断是否相等。 如果不相等:数据传输过程中出错,给出错误应答。 CRC16 校验源码

    2024年02月16日
    浏览(12)
  • 【基础知识】CRC(循环冗余校验)直接计算和查表法

    【基础知识】CRC(循环冗余校验)直接计算和查表法

    校验是什么,个人理解就是经过一个算法,使用大量数据(几MB的数据)生成较小长度的一串信息(如16Bit),并切要做到 原数据不同时,生成的信息大概率不同(不是加密算法不考虑刻意造数据的情况) 原数据中任意一个或几个数据出现错误时,生成的信息不同(所有的原信

    2024年02月05日
    浏览(12)
  • C# | 上位机开发新手指南(五)校验算法——CRC

    C# | 上位机开发新手指南(五)校验算法——CRC

    当我们在进行数据传输时,可能会因为信道噪声、干扰等因素导致数据出现错误,从而影响传输的可靠性和准确性。此时,我们需要一种方法来检测数据是否出现错误,并尽可能快速地发现和纠正错误。CRC(Cyclic Redundancy Check)校验算法就是一种常用的数据校验方法,它通过

    2024年01月18日
    浏览(21)
  • 计算机网络:数据链路层之差错控制、奇偶校验码、CRC循环冗余码、海明码

    计算机网络:数据链路层之差错控制、奇偶校验码、CRC循环冗余码、海明码

    带你度过期末难关 文章目录 一、差错控制 1、冗余编码 2、编码VS编码 二、检错编码 1、奇偶校验码 2、CRC循环冗余码 三、纠错编码————海明码 海明距离 1、确定校验码位数r 2、确定校验码和数据的位置 3、求出校验码的值 4、检错并纠错 纠错的方法一: 纠错方法二: 总

    2024年02月04日
    浏览(9)
  • CRC校验码生成逻辑的实现原理详解——结合C语言和Verilog语言代码分析

    CRC校验码生成逻辑的实现原理详解——结合C语言和Verilog语言代码分析

    因为前段时间用到CRC校验码,所以在网上找到了很多有关CRC校验码计算原理以及生成CRC校验码的代码实现(包括C语言和Verilog语言的实现)的文章,但关于CRC校验码代码实现的原理未能找到相关文章,于是自己结合C语言和Veirlog语言的实现代码以及CRC校验码的计算原理,对CR

    2023年04月22日
    浏览(9)
  • C#: CRC8,CRC16,CRC32 校验代码

    C#: CRC8,CRC16,CRC32 校验代码

    说明:CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定。循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并将得到的结果附在帧的后面,接收设备也执行类似

    2024年01月18日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包