1 原理

参考文档:CRC校验 (qq.com)

参考书籍:《计算机网络(第7版)-谢希仁》

1.1 原理简介

CRC是一种检错方法。

在发送端,先把数据划分为组,假定每组k个比特。现假定待传送的数据M = 101001(k = 6)。CRC运算就是在数据M的后面添加供差错检测用的n位冗余码,然后构成一个帧发送出去,一共发送(k + n)位。

数据:k比特

冗余码:n比特

这n位冗余码可用以下方法得出。在数据M后面添加n个0。得到的(k + n)位的数除以收发双方事先商定的长度为(n + 1)位的除数p(多项式),得出商是Q而余数是R(n 位,比P 少一位,校验码)。

这个余数R就作为冗余码拼接在数据M的后面发送出去。这种为了进行检错而添加的冗余码常称为帧检验序列FCS (Frame Check Sequence) 。

循环冗余检验CRC 和帧检验序列FCS 并不是同一个概念。CRC 是一种检错方法,而FCS 是添加在数据后面的冗余码。

模二运算:也就是异或运算,相同异或为0,不同异或为1。

在接收端把接收到的数据以帧为单位进行CRC检验:把收到的每一个帧都除以同样的除数P(模2运算),然后检查得到的余数R 。如果在传输过程中无差错,那么经过CRC检验后得出的余数R肯定是0。

1.2 计算步骤

(1)先选择CRC多项式,得到多项式的位宽。

例如:选择G(x) = X4 + X3 + 1,对应的二进制编码为:2b'11001,多项式位宽为4。

(2)选择计算的数据。

(3)计算。

计算方式为:在要发送的数据帧(假设为m位)后面加上k-1位“0”(k:多项式位宽),然后使用模二运算得到余数,这个余数就是CRC校验码。

例如:多项式为G(x) = X4 + X3 + 1,计算的数据帧为:2b'10110011,计算过程如下:

得到的CRC校验码为:2b'0100。

2 代码实现

参考链接:数据帧CRC32校验算法实现 - 没落骑士 - 博客园 (cnblogs.com)

在线生成工具:CRC Generation Tool - easics

还是以多项式为G(x) = X4 + X3 + 1,计算的数据帧为:2b'10110011来进行说明。

这里直接说实现,首先使用在线生成工具,得到一个VHDL或者Verilog的CRC校验源码。

然后对下载的代码进行一些改动即可。这里直接给出最后实现的C代码。

#include <stdio.h>

#define int32_t  signed int
#define uint32_t unsigned int
#define uint8_t unsigned char #define GET_BIT_N_VAL(data, n) (0x1 & (( *((data) + (n)/8) & (0x1 << ((n)%8)) ) >> ((n)%8))) #define BITS_TO_BYTES_ARRAY(entry_key, entry_key_bits, bytes_array) \
do \
{ \
uint32_t i = 0; \
for(i = 0; i < (entry_key_bits); i++) \
{ \
bytes_array[i] = GET_BIT_N_VAL((entry_key), i); \
} \
} while (0) #define HASH_KEY_WRITE_BITS 8 uint8_t crc_4_d8(const uint8_t *d) // only use the last one bit
{
/*
-- polynomial: x^4 + x^3 + 1
-- data width: 8
-- convention: the first serial bit is D[7]
*/
int32_t i;
uint8_t ret=0;
uint8_t lfsr_c[4] = {0};
uint8_t c[4] = {0}; lfsr_c[0] = d[7] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ d[0] ^ c[1] ^ c[3];
lfsr_c[1] = d[6] ^ d[4] ^ d[3] ^ d[2] ^ d[1] ^ c[0] ^ c[2];
lfsr_c[2] = d[7] ^ d[5] ^ d[4] ^ d[3] ^ d[2] ^ c[0] ^ c[1] ^ c[3];
lfsr_c[3] = d[7] ^ d[6] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[0] ^ c[2] ^ c[3]; for(i = 0; i < 4; i++)
{
ret |= (lfsr_c[i]<<i);
}
return ret;
} int main(void)
{
uint8_t d = 0xb3;
uint8_t ret = 0;
uint8_t bytes_array[8] = {0}; BITS_TO_BYTES_ARRAY(&d, HASH_KEY_WRITE_BITS, bytes_array); ret = crc_4_d8(bytes_array); printf("ret = 0x%x\n", ret); return 0;
}

编译,运行,结果和之前手动计算的一致。

[grace@localhost] ~/c/crc
$ gcc test_crc.c
[grace@localhost] ~/c/crc
$ ./a.out
ret = 0x4

CRC校验原理简介及C代码实现说明的更多相关文章

  1. CRC 校验原理及步骤

    什么是 CRC 校验? CRC 即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定.循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计 ...

  2. CRC校验原理及步骤

    什么是CRC校验? CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定.循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并 ...

  3. CRC校验原理

    此文为转载文,原作者博客传送门 CRC校验原理 CRC校验原理看起来比较复杂,好难懂,因为大多数书上基本上是以二进制的多项式形式来说明的.其实很简单的问题,其根本思想就是先在要发送的帧后面附加一个数( ...

  4. [技术栈]CRC校验原理及C#代码实现CRC16、CRC32计算FCS校验码

    1.CRC.FCS是什么 CRC,全称Cyclic Redundancy Check,中文名称为循环冗余校验,是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的一种信道编码技术,主要用来检 ...

  5. CRC校验码原理、实例、手动计算

    目录一.CRC16实现代码二.CRC32编码字符表三.CRC校验码的手动计算示例四.CRC校验原理五.CRC的生成多项式参考 一.CRC16实现代码 思路:取一个字符(8bit),逐位检查该字符,如果 ...

  6. CRC校验代码实现

    1.CRC校验简介 CRC就是块数据的计算值,它的全称是“Cyclic Redundancy Check”,中文名是“循环冗余码”.CRC校验是数据通讯中最常采用的校验方式.在嵌入式软件开发中,经常要 ...

  7. CRC码计算及校验原理的最通俗诠释

    5.3.2 循环冗余校验检错方案 奇偶校验码(PCC)只能校验一位错误,本节所要介绍的循环冗余校验码(CRC)的检错能力更强,可以检出多位错误. 1. CRC校验原理      CRC校验原理看起来比 ...

  8. 网络通信 --> CRC校验

    CRC校验 一.什么是CRC校验     循环校验码(Jyclic Redundancy Check,简称CRC码): 是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意 ...

  9. CRC校验8

    什么是CRC校验? CRC即循环冗余校验码:是数据通信领域中最常用的一种查错校验码,其特征是信息字段和校验字段的长度可以任意选定.循环冗余检查(CRC)是一种数据传输检错功能,对数据进行多项式计算,并 ...

随机推荐

  1. JDBC_10_使用Statement实现升序和降序

    使用Statement数据库操作对象实现升序和降序 Statement可以使用在需要SQL语句拼接的情况下,因为在这样的情况下如果使用PreparedStatement就会给需要拼接的某个SQL关键字 ...

  2. PAT归纳总结——一些容易记混的概念

    在刷题的过程中,有时候会遇到一些数据结构中的一些概念,如果对这些概念理解不清楚,甚至理解有误的话,就很可能把题目做错.所以,专门找出在刷题过程中出现的一些概念,以免考试的时候用到想不起来. 拓扑排序 ...

  3. 866. Prime Palindrome

    Find the smallest prime palindrome greater than or equal to N. Recall that a number is prime if it's ...

  4. 794. Valid Tic-Tac-Toe State

    A Tic-Tac-Toe board is given as a string array board. Return True if and only if it is possible to r ...

  5. Redis 面试必备知识点

    1.Redis 简介 是一个用 C 语言开发的,高性能的键值对数据库. 数据存在于内存,读写速度快. 可用来做缓存.分布式锁.消息队列. 提供多种数据类型来支持不同的业务场景. 支持事务.持久化.Lu ...

  6. Aircrack-ng破解无线WIFI密码

    首先,如果kali是装在虚拟机里面的话,是不能用物理机的无线网卡的.所以,如果我们要想进行无线破解,需要外接一个无线网卡设备,并且该设备要支持 monitor 监听模式 iwconfig :系统配置无 ...

  7. Windows核心编程 第十八章 堆栈

    第1 8章 堆 栈 对内存进行操作的第三个机制是使用堆栈.堆栈可以用来分配许多较小的数据块.例如,若要对链接表和链接树进行管理,最好的方法是使用堆栈,而不是第 1 5章介绍的虚拟内存操作方法或第1 7 ...

  8. 三、jmeter常用的元件及组件

    一.HTTP cookie Manager 用来储浏览器产生的用户信息,Stepping Thread Group 可用于模拟阶梯加压! 二.HTTP Cache Manager 缓存管理器(模拟浏览 ...

  9. Asp.NetCore Web应用程序中的请求管道和中间件

    你是否会迷惑当我们请求一个ASP.NetWeb应用程序以后,它是怎么处理这些请求的,后台是怎么工作的,今天就讲一下Asp.NetCore Web应用程序中的请求处理过程. 上一节,我们讲到,Start ...

  10. JavaWeb——反射、注解

    单元测试.反射.注解 1. Junit单元测试 2. 反射 3. 注解 Junit单元测试: * 测试分类: 1. 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值. 2. 白盒测试:需要 ...