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