当前位置: 首页 > article >正文

CRC校验算法以及相关实现示例

一、CRC校验算法介绍

CRC(Cyclic Redundancy Check)校验算法是一种常用的数据传输错误检测算法,它通过对数据进行一个除余运算得到校验码。在发送数据时,发送方先计算出校验码,并将校验码随数据一起发送给接收方;接收方在接收到数据后,也可以重新计算校验码,若接收到的校验码与重新计算出的校验码不同,则说明数据存在错误。

CRC校验算法的实现步骤如下:

  1. 确定生成多项式G(x),该多项式用来产生校验码。

  1. 将要传输的数据以二进制形式填充到一个数据帧中。

  1. 将数据帧左侧补充若干个0,使其位数等于生成多项式G(x)的位数减去1。

  1. 用生成多项式G(x)对新生成的数据帧进行除余运算,得到余数R(x)。

  1. 将余数R(x)作为校验码附加到数据帧的最后面,发送给接收方。

  1. 接收方收到数据帧后,也按照同样的方法计算出校验码,如果计算出的校验码与接收到的校验码相同,则数据传输没有出错。

CRC校验算法具有以下特点:

  1. CRC码是由数据生成的,不必提前设定。

  1. CRC码能够检测出多比特差错,但是不能纠正。

  1. CRC算法可以很容易地在硬件上实现,速度很快。

  1. 不同的生成多项式G(x)可以产生不同的CRC码,因此可以适应不同的数据类型和应用场景。

二、CRC校验算法的Python语言实现

下面是一个简单的CRC校验算法例程,以生成多项式为x^16+x^12+x^5+1(0x1021)为例:

def crc(data):
    # 初始化余数R(x)为全零
    remainder = 0
    # 生成多项式G(x)为x^16+x^12+x^5+1(0x1021)
    generator = 0x1021
    # 将数据帧左侧补充16个0
    data += '\0' * 2
    # 将数据转换成ASCII码
    data = data.encode('ascii')
    # 遍历每一个字节
    for byte in data:
        # 从高位开始处理每一位
        for bit in range(7, -1, -1):
            # 计算R(x)除以G(x)的余数
            if remainder & 0x8000:
                remainder = (remainder << 1) ^ generator
            else:
                remainder = remainder << 1
            # 将当前字节的当前位加入余数中
            if byte & (1 << bit):
                remainder ^= 1
    # 返回计算出的CRC码
    return remainder

该函数接受一个字符串类型的数据作为输入,并返回一个整型数值,即计算出的CRC码。在计算CRC码前,需要将数据帧左侧补充16个0,并将数据转换成ASCII码。遍历每一个字节时,从高位开始处理每一位,并根据余数R(x)是否大于等于生成多项式G(x)来更新余数R(x)。最终得到的余数R(x)就是CRC码。

三、CRC校验算法的C语言实现

以下是一个简单的C语言例程,演示了如何实现CRC校验算法:

#include <stdio.h>

#define POLY 0x1021 //CRC-16校验多项式

unsigned short crc_ccitt(unsigned char *msg, int len)
{
    unsigned short crc = 0xFFFF; //初始值为0xFFFF
 
    for (int i = 0; i < len; i++) {
        crc ^= (unsigned short)msg[i] << 8;
        for (int j = 0; j < 8; j++) {
            if (crc & 0x8000) {
                crc = (crc << 1) ^ POLY;
            } else {
                crc <<= 1;
            }
        }
    }
 
    return crc;
}

int main()
{
    unsigned char msg[] = {0x01, 0x02, 0x03, 0x04};
    int len = sizeof(msg);
    unsigned short crc = crc_ccitt(msg, len);
 
    printf("CRC-16校验结果: 0x%04X\n", crc);
    return 0;
}

在这个例程中,我们使用了CRC-CCITT(XModem)算法来计算CRC校验值。该算法使用了一个16位的多项式0x1021(生成多项式),并通过按位异或、移位等操作对输入数据进行处理,最终得到一个16位的校验值。

在代码中,我们首先定义了一个POLY常量,表示CRC-16多项式。然后我们定义了一个crc_ccitt()函数,用于计算CRC校验值。在这个函数中,我们首先将初始值设为0xFFFF,然后按照CRC算法对输入数据进行处理,并返回计算得到的CRC值。

最后,在主函数中,我们定义了一个测试数据数组msg,并将它传入crc_ccitt()函数中计算得到CRC校验值,并输出结果。


http://www.kler.cn/a/2353.html

相关文章:

  • CS 144 check5: down the stack (the network interface)
  • 一区牛顿-拉夫逊算法+分解+深度学习!VMD-NRBO-Transformer-GRU多变量时间序列光伏功率预测
  • 13.罗意文面试
  • 「Mac畅玩鸿蒙与硬件46」UI互动应用篇23 - 自定义天气预报组件
  • 【Prompt Engineering】7 聊天机器人
  • Connecting to Oracle 11g Database in Python
  • 脱不下孔乙己的长衫,现代的年轻人该怎么办?
  • 百度文心一言正式亮相
  • Linux(网络基础---网络层)
  • 【Python入门第三十五天】Python丨文件打开
  • 论文阅读《Point NeRF:Point-based Neural Radiance Fileds》
  • 【C++进阶】十一、哈希的应用---位图(一)
  • 机器学习算法——决策树详解
  • 蓝桥杯刷题第十五天
  • STM32的CAN总线调试经验分享
  • 【安全与风险】密码学介绍
  • Qt调用Chrome浏览器
  • Qt示例3:用Qt画一个温度计
  • 【thingsboard】实现设备联动
  • 数据结构与算法——二叉树遍历、查找、删除、顺序存储二叉树、线索化二叉树
  • 【数据结构】环形链表
  • 大数据模型、离线架构、实时架构
  • Qt实践项目:仿Everything软件实现一个QtEverything
  • 提高曝光率:外贸网站如何充分利用谷歌优化赢得客户
  • C++成神之路 | 第一课【步入C++的世界】
  • 23种设计模式