1. 程式人生 > >資料傳輸中CRC校驗碼的實現

資料傳輸中CRC校驗碼的實現

CRC校驗碼,即迴圈冗餘校驗(Cyclic Redundancy Check),目前最為常見的一種差錯校驗碼,CRC的資訊欄位和校驗字的長度可以任意選定,在資料傳輸過程中,為了確保資料的正確性,必須使用一種資料檢錯方法,CRC便是最常用的一種。

CRC的原理是若在傳送端傳送資料,假設資料位數為K位,我們可以根據這K位的二進位制碼序列,以一定規則產生一個校驗用的r位監督碼(CRC),與原始資訊一起組成一個新的二進位制碼,這個二進位制碼共有k+r位,然後將這個二進位制碼傳送出去。至於在接收端,根據資訊碼和CRC碼之間的規則進行檢驗,以確定傳送中是否出錯。差錯理論中,稱這個規則為生成多項式。

程式碼如下     
    
   

#include<stdio.h>     
#include<stdlib.h>     
#include<string.h>     
#include<errno.h>     
#include<unistd.h>     
#include<fcntl.h>     
#include<sys/stat.h>     
#define BUFSIZE 1024*4     
    
   
static void usage(void)    
{    
    fprintf(stderr, "Usage: %s input_file\n", program_name);    
}    
  
static void init_crc_table(void)    
{    
    unsigned int c;    
    unsigned int i,j;    
        
    for (i = 0; i < 256; i++) {    
        c = (unsigned )int i;    
        for (j = 0; j < 8; j++) {    
            if (c&1)    
                c = 0xedb88320L^(c>>1);    
            else    
                c = c>>1;    
        }    
        crc_table[i] = c;    
    }    
}    
    
static unsigned int crc32(unsigned int crc,unsigned char *buffer, unsigned int size)    
{    
    unsigned int i;    
    for (i = 0; i < size; i++) {    
        crc = crc_table[(crc ^ buffer[i]) & 0xff] ^ (crc >> 8);    
    }    
    return crc ;    
}    
  
static int calc_img_crc(const char *in_file, unsigned int *img_crc)    
{    
    int fd;    
    int nread;    
    int ret;    
    unsigned char buf[BUFSIZE];    
      
    unsigned int crc = 0xffffffff;     
    
    fd = open(in_file, O_RDONLY);    
    if (fd < 0) {    
        printf("%d:open %s.\n", __LINE__, strerror(errno));    
        return -1;    
    }    
            
    while ((nread = read(fd, buf, BUFSIZE)) > 0) {    
        crc = crc32(crc, buf, nread);    
    }    
    *img_crc = crc;    
    
    close(fd);    
        
    if (nread < 0) {    
        printf("%d:read %s.\n", __LINE__, strerror(errno));    
        return -1;    
    }    
        
    return 0;    
}    
    
int main(int argc, char **argv)    
{    
    int ret;    
    unsigned int img_crc;    
    const char *in_file = argv[1];    
    
    if (argc < 2) {    
        usage();    
        exit(1);    
    }    
    
    init_crc_table();    
        
    ret = calc_img_crc(in_file, &img_crc);    
    if (ret < 0) {    
        exit(1);    
    }    
    
    printf("The crc of %s is:%u\n", in_file, img_crc);    
    
    return 0;    
}