C语言对文件进行crc32校验

C语言对文件进行crc32校验

参考代码(包含测试代码)如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>

#define    POLYCRC32    0XEDB88320L            //CRC32标准
static uint32_t crc_table32[256];        //CRC查询表
#define    TEST_FILE_PATH    "test/testfile"
//生成CRC查询表
void init_crc32_tab()
{
    int32_t i, j;
    uint32_t crc;

    for(i = 0; i < 256; i++)
    {
        crc = (uint32_t )i;
        for(j = 0; j < 8; j++)
        {
            if(crc & 0X00000001L)
            {
                crc = (crc >> 1) ^ POLYCRC32;
            }
            else
            {
                crc = crc >> 1;
            }
        }
        crc_table32[i] = crc;
    }

}

//获得CRC
uint32_t get_crc(uint32_t crcinit, uint8_t *bs, uint32_t bssize)
{
    uint32_t crc = crcinit ^ 0XFFFFFFFF;
    while(bssize--)
    {
        crc = (crc>>8)^crc_table32[(crc&0XFF)^*bs++];
    }
    return crc ^ 0XFFFFFFFF;
}

//获得文件CRC

int32_t calc_img_crc(const char *pFileName, uint32_t *uiCrcValue)
{
    if(!pFileName || !uiCrcValue)
    {
        printf("bad parameter\n");
        return -1;
    }
    if(access(pFileName, F_OK|R_OK)!=0)
    {
        printf("file not exist or reading file has not permission\n");
        return -1;
    }
    const uint32_t size = 16*1024;
    uint8_t crcbuf[size];
    uint32_t rdlen;
    uint32_t crc = 0;  // CRC初始值为0

    FILE *fd = NULL;
    if((fd = fopen(pFileName, "r"))==NULL)
    {
        printf("to do crc 32 check, open file error\n");
        return -1;
    }
    while((rdlen=fread(crcbuf, sizeof(uint8_t), size, fd))>0)
    {
        crc = get_crc(crc, crcbuf, rdlen);
    }
    *uiCrcValue = crc;
    fclose(fd);
    return 0;
}

unsigned char *read_test_file(const char *path, int *file_size)
{
    if(!path||!file_size)
    {
        printf("bad parameter\n");
        return NULL;
    }
    //access
    if(access(path, F_OK|R_OK))
    {
        printf("access test file error\n");
        return NULL;
    }
    //read file
    struct stat calib_stat;
    int ret = stat(path, &calib_stat);
    if(ret!=0)
    {
        printf("File error\n");
        return NULL;
    }
    int fd = open(path, O_RDONLY);
    if(fd<0)
    {
        printf("Open test file error");
        return NULL;
    }
    unsigned char *buffer = malloc(calib_stat.st_size);
    if(!buffer)
    {
        printf("malloc error\n");
        close(fd);
        return NULL;
    }

    memset(buffer, 0, calib_stat.st_size);
    int totalSize = 0, readed = 0;
    while((readed = read(fd, buffer + totalSize, 1024)) > 0)
    {
        totalSize += readed;
    }
    *file_size = totalSize;
    close(fd);
    return buffer;
}

int32_t main()
{
    init_crc32_tab();
    uint32_t crc_value = 0;
    if(calc_img_crc(TEST_FILE_PATH, &crc_value) == 0)
    {
        printf("crc_value = %x\n", crc_value);
    }
    else
    {
        printf("calculate crc 32 value error\n");
        exit(0);
    }
    int size = 0;
    unsigned char *file = read_test_file(TEST_FILE_PATH, &size);
    if(!file)
    {
        printf("read test file error\n");
        exit(0);
    }
    unsigned char *f = file;
    printf("size=%d\n", size);
    int i=0;
    while(i<size)
    {
        printf("%x ", f[i]);
        i++;
    }
    free(file);
    printf("\n");
    printf("i=%d\n",i);
    return 0;
}

以上代码执行会计算出一个文件的crc32值,同时可以将文件的16进制hex数据输出出来,可以将16进制的hex数据进行验证,分享一个验证crc32计算结果的网站。
CRC(循环冗余校验)在线计算:http://www.ip33.com/crc.html
本文参考了以下内容,对以下作者表示感谢。
https://www.cnblogs.com/milanleon/p/8805358.html
http://www.360doc.com/content/14/0225/10/7775902_355489982.shtml

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
CRC(循环冗余校验)是一种错误检测代码,常用于数据通信和存储系统中,用于检测和纠正数据传输或存储过程中的错误。CRC-32是其中一种常用的校验码。下面是使用C语言实现CRC-32校验的简单示例: 首先,我们需要一个用于计算CRC-32的查表(lookup table)。该查表包含了所有256个可能的字节值对应的CRC-32值。 ```c #include <stdio.h> unsigned int crc32_table[256]; void create_crc32_table() { unsigned int crc, i, j; for(i = 0; i < 256; i++) { crc = i; for(j = 0; j < 8; j++) { if(crc & 1) { crc = (crc >> 1) ^ 0xEDB88320; } else { crc = crc >> 1; } } crc32_table[i] = crc; } } ``` 然后,我们可以使用该查表来计算给定数据的CRC-32校验值。 ```c unsigned int calculate_crc32(unsigned char *data, int length) { unsigned int crc = 0xFFFFFFFF; int i; for(i = 0; i < length; i++) { crc = (crc >> 8) ^ crc32_table[(crc & 0xFF) ^ data[i]]; } return crc ^ 0xFFFFFFFF; } int main() { create_crc32_table(); unsigned char data[] = {0x01, 0x02, 0x03}; unsigned int crc32 = calculate_crc32(data, sizeof(data)); printf("CRC-32: 0x%08X\n", crc32); return 0; } ``` 上述代码中,我们首先调用`create_crc32_table`函数来生成CRC-32查表。然后,我们可以通过调用`calculate_crc32`函数来计算给定数据的CRC-32校验值。在`main`函数中,我们使用示例数据`{0x01, 0x02, 0x03}`来进行测试,并打印出计算得到的CRC-32校验值。 以上就是使用C语言实现CRC-32校验的简单示例。通过使用CRC校验码,可以有效地检测和纠正数据传输或存储过程中的错误,提高数据的可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值