CRC 校验算法

皓然123 / 2024-10-22 / 原文

什么是CRC

CRC(Cyclic Redundancy Check)校验算法是一种广泛应用于数据通信和存储系统中的错误检测方法,主要用于检测数据在传输过程中是否发生了改变。CRC算法通过计算一个固定长度的校验码,将该校验码附加到原始数据的末尾,接收方在接收到数据后重新计算校验码并与接收到的校验码进行比较,以此判断数据在传输过程中是否发生了错误。这种校验机制不仅能够检测出大多数类型的错误,而且计算效率高,占用资源少,因此在各种通信协议、文件系统、磁盘驱动器和网络协议中都有广泛应用。

 

原理

感觉太繁杂了,半天看不懂,自己看下面的链接吧:

https://blog.csdn.net/xiaolong1126626497/article/details/141155059

 

CRC32 实验代码

crc32 是应用比较广泛的,而且能检测大部分错误。这里以CRC32 为例,写个例子,方便以后使用。

其中查表法,对于计算CRC较快,所以是用查表法实现:

这里使用的是IEEE 802.3标准的多项式(0x04C11DB7),这是最常用的CRC32实现。

#include <stdio.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>

// CRC32 IEEE 802.3生成多项式
#define POLYNOMIAL 0x04C11DB7

// 初始化CRC32查找表
uint32_t crc32_table[256];

void init_crc32_table(void)
{
    uint32_t crc, poly;
    uint16_t i, j;

    for (i = 0; i < 256; i++)
    {
        crc = i;
        for (j = 8; j; j--)
        {
            if (crc & 0x00000001)
                crc = (crc >> 1) ^ POLYNOMIAL;
            else
                crc >>= 1;
        }
        crc32_table[i] = crc;
    }
}

uint32_t crc32(const void *data, size_t len)
{
    const uint8_t *byte = data;
    uint32_t crc = 0xFFFFFFFF;

    while (len--)
    {
        crc = (crc >> 8) ^ crc32_table[(crc ^ *byte++) & 0xFF];
    }

    return crc ^ 0xFFFFFFFF;
}

int main(int argc, char *argv[])
{
    int fd;
    uint8_t buffer[4096];
    size_t bytes_read;
    uint32_t crc;

    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s filename\n", argv[0]);
        return 1;
    }

    // 初始化CRC32查找表
    init_crc32_table();

    // 打开文件
    fd = open(argv[1], O_RDONLY);
    if (fd == -1)
    {
        perror("Error opening file");
        return 1;
    }

    // 读取文件并计算CRC32校验值
    crc = 0xFFFFFFFF;
    while ((bytes_read = read(fd, buffer, sizeof(buffer))) > 0)
    {
        crc = crc32(buffer, bytes_read);
    }

    close(fd);

    // 输出CRC32校验值
    printf("CRC32 checksum: 0x%08X\n", crc);

    return 0;
}

  

在这个示例中,init_crc32_table函数初始化了CRC32的查找表,crc32函数用于计算输入数据的CRC32校验值。主函数main负责读取文件内容并调用crc32函数计算CRC32校验值,最后输出该值。

注意,在CRC32计算结束时,通常需要对CRC值进行反转(XOR 0xFFFFFFFF),这是为了与大多数CRC32实现保持一致。

测试

新建file.txt,内容为:this is a test file for crc32

结果

./crc_32 file.txt
CRC32 checksum: 0xF9FF0706

记录一下,方便以后使用吧。