c++ 证书校验代码_信道编码之循环冗余校验(CRC)

481e40148230c933d2c17c9e352c3f25.png

香农在其著名的论文《A mathematical theory of communication》中提出了信道编码定理,在传输速率小于信道容量的情况下,可以通过编码非常高效的提高传输的可靠性。我们现在所说的信道编码主要指的是纠错编码,比如卷积码,汉明码,Turbo码和LPDC码等等。本文主要研究在这些编码技术中比较常用的一种检验技术,即CRC。

CRC技术也是通过增加信道的冗余来提高传输的可靠性,不但能够起到校验的作用同时也具备一定的纠错能力。CRC算法的实现是基于循环码的,其数学原理在于通过发射端信息做一个多项式除法,得到余数作为检验位,然后将其加入原始信息的后面。在接收端提取发射端的数据位然后做相同的求余运算,再将计算出的校验位和发送数据带有的检验位相对比,若相同则说明数据是正确的,若不同说明数据是错误的。下图展示了一个简单的CRC结构:

d597bed354d0311f3b96a5cd27754a53.png

前面说了CRC的原理是做除法取余数,这里就涉及了一个除法项,我们称之为生成多项式(Generator Polynomial),这个生成多项式是发送机和接收机两端约定好的一个二进制序列,在整个传输过程中保持不变。这个生成多项式同时满足如下几个条件:

  1. 最高位和最低为为1
  2. 当传输信息任何1位发生错误时,被其除后余数不为0
  3. 不同位数发生错误时,余数不同。
  4. 对于余数做除法,应使余数循环。

这里我们以一个简单的CRC-4为例,来解释生成多项式的作用和CRC校验的原理:

CRC-4的常用的一个生成多项式为:

即10011,其求余过程如下图所示:

513a3a368a78bc84cd0e862cdc593c01.png

最后的发送数据就为:

f33a3aa722753843644fb503eb183ec3.png

其实现的Matlab代码如下:

InputBits = [1 0 1 1 0 0 1 1 ];
Poly =[1 0 0 1 1];%Poly多项式
length_data=size(InputBits,2)      
length_Poly=size(Poly,2)     
for i=length_data+1:length_data+length_Poly-1                 
  InputBits(1,i)=0;
end

for i=1:length_data                 
  OutputBits(1,i)=InputBits(1,i);
end
%异或操作
i=1;
while(i<=length_data)                   
    for m=1:length_Poly                 
        if InputBits(1,i)==Poly(1,m)
            InputBits(1,i)=0;
        else InputBits(1,i)=1;
        end                            
        i=i+1;m=m+1;
    end
    i=i-1;
    for j=i-(length_Poly-1):i            %定位异或初始位置
        if InputBits(1,j)==0
            j=j+1;
        else break;
        end
    end
    i=j;
end

CRCout=zeros(1,length_Poly-1);                 
for i=1:length_Poly-1
    CRCout(1,i)=InputBits(1,length_data+i);      %余数 即CRC码
    OutputBits(1,i+length_data)=CRCout(1,i);      %添加CRC
end
disp('output bits are :');
OutputBits
disp('CRC are :');
CRCout           

最终输出的结果为:

42ea2e91bf23d8a407135d1f3143ca43.png

和上面手算的相同。


软件仿真结束后我们就可以开始使用硬件进行实现了,我个人实现的思路是通过状态机来实现上述matlab代码中的循环运算,首先设定一个数据位宽长度计数器width cont,每当进来一次有效的数据,判断其最高位是否为1,若否则左移一位width cont减1,找到其最高位为1的数据后进入下一个状态进行xor运算,在xor状态中将数据和poly 序列进行xor运算,随后在进入刚才的判断状态,找到最高位为1的位置,直到width cont < poly序列的长度时结束计算,然后保存余数,跳入等待下一个有效数据计算的状态。正当我兴致冲冲打算去码代码的时候,发现了一个神奇的网站可以直接生成CRC校验的代码。。。

CRC Generation Tool​www.easics.com
a7efebaa4473055a292dc764bc21584a.png

只要选择好poly多项式和数据位宽就可以直接生成verilog代码,十分方便:

8cf5d398835fd402e4d3b18a13386627.png

生成代码如下:

  // polynomial: x^4 + x^1 + 1
  // data width: 24
  // convention: the first serial bit is D[23]
  function [3:0] nextCRC4_D24;

    input [23:0] Data;
    input [3:0] crc;
    reg [23:0] d;
    reg [3:0] c;
    reg [3:0] newcrc;
  begin
    d = Data;
    c = crc;

    newcrc[0] = d[23] ^ d[21] ^ d[19] ^ d[18] ^ d[15] ^ d[11] ^ d[10] ^ d[9] ^ d[8] ^ d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[1] ^ c[3];
    newcrc[1] = d[23] ^ d[22] ^ d[21] ^ d[20] ^ d[18] ^ d[16] ^ d[15] ^ d[12] ^ d[8] ^ d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[1] ^ c[2] ^ c[3];
    newcrc[2] = d[23] ^ d[22] ^ d[21] ^ d[19] ^ d[17] ^ d[16] ^ d[13] ^ d[9] ^ d[8] ^ d[7] ^ d[6] ^ d[4] ^ d[2] ^ d[1] ^ c[1] ^ c[2] ^ c[3];
    newcrc[3] = d[23] ^ d[22] ^ d[20] ^ d[18] ^ d[17] ^ d[14] ^ d[10] ^ d[9] ^ d[8] ^ d[7] ^ d[5] ^ d[3] ^ d[2] ^ c[0] ^ c[2] ^ c[3];
    nextCRC4_D24 = newcrc;
  end
  endfunction

这是个函数形式的代码,并且通过并行的形式直接可以计算出CRC的几个余数,效率简洁高效,我暂时还没看懂这个代码是什么原理,懂得大佬可以指点一下。

随后在发射端只要进行一个简单的CRC编码:

    always @ ( * )
    begin
        crc_cal_data = CRC4_D24(adc_data[27:4],4'b0);
        tx_data  = {adc_data[27:4],crc_cal_data};
    end

接收端校验使用的方法为:

    always @ ( * )
    begin
        crc_test_data = CRC4_D24(tx_data[27:4],4'b0);
        crc_rx_data  = tx_data[3:0];

        if ( crc_test_data  != crc_rx_data  )
            ccr_error = 1'b1;
        else
            ccr_error = 1'b0;
    end

具体的仿真结果这里就没有做了,等有空再补上~

参考文献

[1] 王栋. 基于CRC的多比特纠错算法研究与实现[D].西安电子科技大学,2013.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: CRC循环冗余校验)是一种常用的错误检测技术。CRC主要通过附加一个固定长度的校验码到数据中,来检测数据在传输过程中是否发生了错误。在CRC中,校验码是通过对数据进行除法运算得到的。 具体而言,给定一个二进制的数据块D,CRC会附加一个n位的校验码C到数据末尾,形成一个新的数据块D'C。校验码C被设计为使得D'C能够被一个特定的生成多项式G整除,如果在传输过程中发生了错误,这个多项式无法整除D'C,因此可以通过检查余数来判断是否发生了错误。 CRC的关键是选择适当的生成多项式G。常见的生成多项式包括CRC-8、CRC-16和CRC-32等。不同的生成多项式会产生不同长度的校验码,长度越长,检测到错误的可能性越高。 在进行CRC运算时,接收方会将接收到的数据块D'C除以生成多项式G。如果余数为0,则表明没有错误;如果余数不为0,则表明发生了错误。在这种情况下,接收方可以向发送方请求重新发送数据,以确保数据的正确性。 总而言之,CRC是一种通过附加校验码到数据中的方法,可以有效地检测传输过程中的错误。通过选择适当的生成多项式,可以提高CRC的检测能力。 ### 回答2: CRC循环冗余校验)是一种常见的错误检测技术,用于检测数据传输过程中是否发生了错误。它使用多项式除法的原理,将输入数据与生成多项式进行模2除法运算,得到校验码,然后将校验码附加到原始数据中进行传输,接收方再次进行CRC运算并检查校验码是否匹配,从而判断数据是否出现错误。 CRC算法主要基于封闭性和循环性的原则,它将传输的数据看作二进制数,使用一个生成多项式进行除法运算。该生成多项式在CRC算法中是固定的,不同的生成多项式对应不同的CRC校验码。一般情况下,生成多项式选取低于数据位数的最高次项为1,其余项为0。 CRC过程中,首先需要进行数据的比特填充,即将数据位数按照生成多项式的次数进行扩展,扩展的位数是生成多项式的位数减1。然后进行模2除法运算,逐位比较输入数据和生成多项式的对应位,若两位相同,则结果为0,否则为1。运算结束后得到CRC校验码,然后将其附加到原始数据后面,发送给接收方。 接收方收到数据后,同样经过除法运算得到接收到的校验码。如果接收到的校验码与发送方计算的校验码相同,说明数据传输过程中没有发生错误。如果两个校验码不匹配,则表示数据存在错误,需要重传或进行其他处理。 CRC循环冗余校验是一种简单、高效且广泛应用的错误检测技术,它能够检测发生在数据传输过程中的大多数错误,并且具有较低的错误漏检率和错误检测率。在网络通信、存储系统、计算机硬件等领域广泛应用,能够确保数据的完整性和可靠性。 ### 回答3: CRC循环冗余校验)是一种常用的数据校验方法。在计算机通信和存储中,为了确保数据的完整性和准确性,我们经常需要对数据进行校验CRC是通过对数据进行除法运算来实现的。 CRC校验的基本原理是,将数据看作二进制多项式,然后利用除法运算来计算其余数。具体步骤如下: 1. 将待校验的数据表示为二进制形式,并在最高位补充k个0,其中k为CRC校验码的位数。 2. 选择一个固定的生成多项式G(x),作为除数。该多项式的系数即为CRC校验码的系数。 3. 将生成多项式G(x)左移k位,与待校验数据相异或。 4. 重复步骤3,直到所有数据位都被处理完。 5. 最后所得结果就是校验码,可以将其附加在原始数据后面发送。 6. 接收方根据接收到的数据,再次进行CRC校验。如果余数为0,则认为数据没有出错;反之,则认为数据出错。 CRC可以提供较高的校验效率和误码检测能力,常被应用于计算机网络、存储器、传感器等领域。它的优点是计算简单、校验速度快,并且能够检测到多种错误,包括单比特差错、双比特差错和突发差错等。 总而言之,CRC循环冗余校验是一种常用的数据校验方法,通过除法运算来计算校验码,并能够高效地检测数据的错误。它在通信和存储领域发挥着重要作用,确保了数据的完整性和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值