crc校验代码

来源:互联网 发布:mysql分页查询语句 编辑:程序博客网 时间:2024/04/29 14:45

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

#define CRC32_MAGIC_NUMBER (0xEDB88320)
#define CRC32_TABLE_LENGTH (256)
#define BUFF_DATA_LEN (4*1024)

typedef unsigned int u32;
typedef unsigned char u8;

u32 * global_crc32_table;

u32 * generate_crc32_table(void)
{
        u32 poly_nomial = CRC32_MAGIC_NUMBER;
        int i, j;
        u32 * crc32_table = NULL;
        u32 crc;

        crc32_table = (u32 *)malloc(sizeof(u32) * CRC32_TABLE_LENGTH);
        if (NULL == crc32_table)
        {
                return NULL;
        }

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

        return crc32_table;
}

void release_crc32_table(u32 * crc32_table)
{
        if (NULL != crc32_table)
        {
                free(crc32_table);
        }
}

void calc_crc32(u8 byte, u32 * crc32)
{
        *crc32 = (((*crc32)) >> 8) ^ global_crc32_table[(byte) ^ ((*crc32) & 0x000000FF)];
}

int crc32_check(char * file_name, u32 * crc32_value)
{
        u32 fd;
        struct stat stat_buf;
        u32 file_len;
        u32 * tmp_data;
        u32 tmp_len;
        u32 read_count;
        u32 crc32 = 0xffffffff;
        int ret;
        int loop;

        if (NULL == file_name)
                return -1;

        fd = open(file_name, O_RDWR);

        tmp_data = (u32 *)malloc(BUFF_DATA_LEN);

        if (ret = stat(file_name, &stat_buf))
        {
                printf("get file stat error %d.\n", ret);
                return ret;
        }
        else
                file_len = stat_buf.st_size;

                printf("file len %d\n", file_len);
        do
        {
                tmp_len = (file_len > BUFF_DATA_LEN) ? BUFF_DATA_LEN : file_len;
                read_count = read(fd, tmp_data, tmp_len);
                file_len -= read_count;
                for (loop = 0; loop < read_count; loop++)
                {
                        calc_crc32(tmp_data[loop], &crc32);
                }
                crc32 = ~crc32;
                *crc32_value = crc32;
        }
        while ((read_count > 0) && file_len);

        free(tmp_data);
        close(fd);

        return 0;
}

int main(int argc, char * argv[])
{
        u32 val;
        char file_path[80];

        global_crc32_table = generate_crc32_table();
        if (NULL == global_crc32_table)
        {
                return -1;
        }

        sprintf(file_path, "%s", argv[1]);
        crc32_check(file_path, &val);

        release_crc32_table(global_crc32_table);

        printf("crc = %x\n", val);

        return 0;
}