如何理解CRC循环冗余校验——图解CRC算法模型和C语言实现

如何理解CRC循环冗余校验

循环冗余校验(英语:Cyclic redundancy check,通称“CRC”)是一种产生定长校验码的算法,主要用来检测或校验数据传输或者保存后可能出现的错误。

它真的太常见了,上至应用软件通信和网络数据传输,下至芯片烧写、主从设备交互,好像凡是涉及通信,就免不了存在CRC校验。但它又太令人陌生了,习以为常地使用它,默认它的存在却不了解它的实现,想起来也的确是一件憾事,故而翻了翻论文,写点笔记放在这里。


1 资料追溯

据这篇文章

Tingilkar K, Reddy S K. Improvement Of Memory Data Corrections By Using CRC Technique For Fault Torrent Applications[J].

CRC理论最初由W. Wesley Peterson于1961年发表。


基本概念
简单说来,这个算法就是一个求给定序列的校验和(checksum)的算法:

CRC (Cyclic Redundancy Check) is a checksum algorithm.

它是定长多项式与输入比特流做模二除法以后的余数:

CRC is the remainder after division of a long input binary bitstream with fixed length polynomial.

我们也可以把CRC算法理解为一个有任意初值的移位寄存器。例如:输入比特流不断左移,在最左端的那一位满足条件时,通过规定的运算更新寄存器的值,最后寄存器里剩下的那个数就是我们要求的校验和:

CRC can also be considered as shift register. Original register value can be zero or non-zero.
Input bitstream is fed bit by bit and when it is finished, left register value is called ‘CRC’.

这里所说的“规定的运算”,就是让寄存器的值和多项式做异或运算:

Register is XORed with polynomial after every bit shift if out MSB value is ‘1’.


2 图解算法

需要形象一些的话,可以看下面这张图。输入比特流Input bits一位一位地进入一个左移寄存器(Left Shift Register, LSR),假如最左端出去的那一bit是1的话,左移寄存器的值就更新为当前LSR中的值与多项式异或的结果。然后再输入下一bit。

请添加图片描述


3 参数

从图解中可以知道,要实现CRC,至少需要知道左移寄存器的位宽和初值、用以进行异或运算的多项式(一个位宽与左移寄存器一致的0/1序列),此外再知道输入比特流和它的长度就可以进行CRC计算了。

/*
------------------------------------------------
CRC需要的参数		说明
------------------------------------------------
位宽				寄存器、多项式和校验和的位宽
输入				输入比特流的内容
输入长度				输出比特流的bit数
------------------------------------------------
*/

4 库

可以使用Github仓库:crc-lib-c
包含头文件就可以使用

#include <stdio.h>
#include <stdlib.h>
#include "crcLib.h"

int main()
{
    
    
    uint8_t data;	//输入
    uint8_t crc;	//输出
   
    data = 0x34;	//8-bits比特流输入(0011 0100)
    crc = crc8_maxim(&data, 1);		

    printf("data:%02x, crc:%02x\n", data, crc);
    return 0;
}

这个仓库里还有在线工具:CRC在线计算器


猜你喜欢

转载自blog.csdn.net/qq_33904382/article/details/128121025