找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3894|回复: 0

CRC32校验算法-C实现 |gzshun

[复制链接]
发表于 2011-12-18 10:37:19 | 显示全部楼层 |阅读模式
CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中最常用的一种差错校验码,其特征是信息字段和校验字段的长度可以任意选定。
CRC校验实用程序库在数据存储和数据通讯领域,为了保证数据的正确,就不得不采用检错的手段。
以下是CRC32的C语言实现,经过测试,能够正确运行:
  1. /*****************************************************
  2. ** Name         : imagehead.c
  3. ** Author       : gzshun
  4. ** Version      : 1.0
  5. ** Date         : 2011-12
  6. ** Description  : CRC32 Checking
  7. ******************************************************/
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <errno.h>
  12. #include <unistd.h>
  13. #include <fcntl.h>
  14. #include <sys/stat.h>
  15. #define BUFSIZE     1024*4
  16. static unsigned int crc_table[256];
  17. const static char * program_name = "crc32";
  18. static void usage(void);
  19. static void init_crc_table(void);
  20. static unsigned int crc32(unsigned int crc, unsigned char * buffer, unsigned int size);
  21. static int calc_img_crc(const char * in_file, unsigned int * img_crc);
  22. static void usage(void)
  23. {
  24.         fprintf(stderr, "Usage: %s input_file\n", program_name);
  25. }
  26. /*
  27. **初始化crc表,生成32位大小的crc表
  28. **也可以直接定义出crc表,直接查表,
  29. **但总共有256个,看着眼花,用生成的比较方便.
  30. */
  31. static void init_crc_table(void)
  32. {
  33.         unsigned int c;
  34.         unsigned int i, j;
  35.        
  36.         for (i = 0; i < 256; i++) {
  37.                 c = (unsigned int)i;
  38.                 for (j = 0; j < 8; j++) {
  39.                         if (c & 1)
  40.                                 c = 0xedb88320L ^ (c >> 1);
  41.                         else
  42.                                 c = c >> 1;
  43.                 }
  44.                 crc_table[i] = c;
  45.         }
  46. }
  47. /*计算buffer的crc校验码*/
  48. static unsigned int crc32(unsigned int crc,unsigned char *buffer, unsigned int size)
  49. {
  50.         unsigned int i;
  51.         for (i = 0; i < size; i++) {
  52.                 crc = crc_table[(crc ^ buffer[i]) & 0xff] ^ (crc >> 8);
  53.         }
  54.         return crc ;
  55. }
  56. /*
  57. **计算大文件的CRC校验码:crc32函数,是对一个buffer进行处理,
  58. **但如果一个文件相对较大,显然不能直接读取到内存当中
  59. **所以只能将文件分段读取出来进行crc校验,
  60. **然后循环将上一次的crc校验码再传递给新的buffer校验函数,
  61. **到最后,生成的crc校验码就是该文件的crc校验码.(经过测试)
  62. */
  63. static int calc_img_crc(const char *in_file, unsigned int *img_crc)
  64. {
  65.         int fd;
  66.         int nread;
  67.         int ret;
  68.         unsigned char buf[BUFSIZE];
  69.         /*第一次传入的值需要固定,如果发送端使用该值计算crc校验码,
  70.         **那么接收端也同样需要使用该值进行计算*/
  71.         unsigned int crc = 0xffffffff;
  72.         fd = open(in_file, O_RDONLY);
  73.         if (fd < 0) {
  74.                 printf("%d:open %s.\n", __LINE__, strerror(errno));
  75.                 return -1;
  76.         }
  77.                
  78.         while ((nread = read(fd, buf, BUFSIZE)) > 0) {
  79.                 crc = crc32(crc, buf, nread);
  80.         }
  81.         *img_crc = crc;
  82.         close(fd);
  83.        
  84.         if (nread < 0) {
  85.                 printf("%d:read %s.\n", __LINE__, strerror(errno));
  86.                 return -1;
  87.         }
  88.        
  89.         return 0;
  90. }
  91. int main(int argc, char **argv)
  92. {
  93.         int ret;
  94.         unsigned int img_crc;
  95.         const char *in_file = argv[1];
  96.         if (argc < 2) {
  97.                 usage();
  98.                 exit(1);
  99.         }
  100.         init_crc_table();
  101.        
  102.         ret = calc_img_crc(in_file, &img_crc);
  103.         if (ret < 0) {
  104.                 exit(1);
  105.         }
  106.         printf("The crc of %s is:%u\n", in_file, img_crc);
  107.         return 0;
  108. }
复制代码

/*
**测试程序
**环境:
**Linux ubuntu 2.6.32-24-generic-pae #39-Ubuntu SMP Wed Jul 28 07:39:26 UTC 2010 i686 GNU/Linux
**gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
**
gzshun@ubuntu:~/apue/crc32$ ls
crc32.c
gzshun@ubuntu:~/apue/crc32$ gcc crc32.c -o crc32
gzshun@ubuntu:~/apue/crc32$ ./crc32 crc32.c
The crc of crc32.c is:3892136086
*/


作者:gzshun 发表于2011-12-17 21:28:52 原文链接
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-4-19 17:22 , Processed in 0.012080 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表