user-0 提问: 怎么对一个大文件分块求crc校验值

回复:
user: user-1
content: 自己把多个文件并在一个流里也行。单独（用同一个多项式）做CRC然后合并起来也行（衔接点需要多做log(文件大小)的计算）。取决于使用场景。

user: user-2
content: 引用 4 楼 calen_ 的回复:英特尔处理器上有个 _mm_crc32_u32 ，楼主可以去研究一下，据说这一条指令只需要4个周期。 理论上来说所有计算crc的算法都是分块的，把前一块的crc与后一块的前32位xor，然后正常地去算后一块，结果就是连起来的。 SSE4.2的CRC32和有些不一样吧

user: user-3
content: 英特尔处理器上有个 _mm_crc32_u32 ，楼主可以去研究一下，据说这一条指令只需要4个周期。 理论上来说所有计算crc的算法都是分块的，把前一块的crc与后一块的前32位xor，然后正常地去算后一块，结果就是连起来的。

user: user-4
content: 最后一个少了 CRC32_Final(&ctx, crc32);

user: user-4
content: http://bbs.csdn.net/topics/391807382 看我的 #5 回复。一般这类计算 hash 的都会由一个 Init、Update、Final 函数。你只需要多次调用 Update 即可将大数据分块计算。举例如下：unsigned char crc32[4] = { 0 }; const unsigned char crcBuff[] = "abcdef";  // 以下三种形式计算 abcdef 字符串结果相同 CRC32_CTX ctx = { 0 };  CRC32_Init(&ctx); // 分块计算 CRC32_Update(&ctx, &crcBuff[0], 2); // 分块计算 CRC32_Update(&ctx, &crcBuff[2], 2); // 分块计算 CRC32_Update(&ctx, &crcBuff[4], 2); CRC32_Final(&ctx, crc32);  printf("%02X%02X%02X%02X\n", crc32[0], crc32[1], crc32[2], crc32[3]);  CRC32_Init(&ctx); // 分块计算 CRC32_Update(&ctx, &crcBuff[0], 4); // 分块计算 CRC32_Update(&ctx, &crcBuff[4], 2); CRC32_Final(&ctx, crc32);  printf("%02X%02X%02X%02X\n", crc32[0], crc32[1], crc32[2], crc32[3]);  CRC32_Init(&ctx); // 分块计算 CRC32_Update(&ctx, &crcBuff[0], 6);  printf("%02X%02X%02X%02X\n", crc32[0], crc32[1], crc32[2], crc32[3]);

user: user-5
content: 仅供参考：#include <sys\stat.h> #include <io.h> #include <fcntl.h> #include <share.h> #include <stdlib.h> #include <stdio.h> #include <conio.h> #include <string.h> #define MAX_CLU_BYTES 65536 FILE *fo; int fh; __int64 offs,offs1; __int64 rvi64; int rv,wrv; unsigned char buf[MAX_CLU_BYTES]; char ofn[_MAX_PATH]; char offstr[80]; char drive[_MAX_DRIVE]; char dir[_MAX_DIR]; char fname[_MAX_FNAME]; char ext[_MAX_EXT]; char fullpath[_MAX_PATH]; void strcpybutcomma(char *t,char *s) {     char c;      while (1) {         c = *s++;         if (','!=c) *t++ = c;         if (0==c) break;     } } int main(int argc,char **argv) {     if (argc<3) {         printf("Copy File Tail.\n");         printf("Usage:\n");         printf("    cft filename.ext {Offset_Begin|-Offset_End|Offset_Begin-Offset_End}\n");         printf("Copy filename.ext {OB|-OE|OB-OE} to {OB|~OE|OB-OE}-filename.ext\n");         printf("Note: Byte at OE is NOT included.\n");         printf("Example:\n");         printf("    cft abc.rar 12345\n");         printf("Copy abc.rar offset 12345-end to 12345-abc.rar\n");         printf("    cft abc.rar -12345\n");         printf("Copy abc.rar offset -12345-end to ~12345-abc.rar\n");         printf("    cft abc.rar 123-12345\n");         printf("Copy abc.rar offset 123-12345 to 123-12345-abc.rar\n");         printf("    cft abc.rar 0xAB-0xCD\n");         printf("Copy abc.rar offset 0xAB-0xCD to 0xAB-0xCD-abc.rar\n");         return 1;     }     strcpybutcomma(offstr,argv[2]);     rv=sscanf(offstr,"%I64i-%I64i",&offs,&offs1);     if (rv==0) {         printf("offset %s is not number\n",argv[2]);         return 2;     }     if (NULL==_fullpath(fullpath,argv[1],_MAX_PATH)) {         printf("Can not get fullpath of %s\n",argv[1]);         return 10;     }     fh=_sopen(fullpath,_O_BINARY|_O_RDONLY|_O_RANDOM,_SH_DENYNO);     if (fh==-1) {         printf("_sopen %s errno=%d %s\n",fullpath,errno,strerror(errno));         return 3;     }     if (rv==1) {         offs1=_filelengthi64(fh);         if (offs1==-1i64) {             printf("%I64d=_filelengthi64 errno=%d %s\n",offs1,errno,strerror(errno));             _close(fh);             return 4;         }         if (offs<0i64) {             offs=offs1+offs;             if (offs<0i64) offs=0i64;         }     } else {//rv==2         if (offs>offs1) {             printf("%s offset_begin %I64d > %I64d offset_end error\n",argv[2],offs,offs1);             _close(fh);             return 5;         }     }     rvi64=_lseeki64(fh,offs,SEEK_SET);     if (rvi64!=offs) {         printf("%I64d=_lseeki64 %I64d errno=%d %s\n",rvi64,offs,errno,strerror(errno));         _close(fh);         return 6;     }     _splitpath(fullpath,drive,dir,fname,ext);     if (offstr[0]=='-') offstr[0]='~';     sprintf(ofn,"%s%s%s-%s%s",drive,dir,offstr,fname,ext);     fo=fopen(ofn,"wb");     if (fo==NULL) {         printf("fopen %s errno=%d %s\n",ofn,errno,strerror(errno));         _close(fh);         return 7;     }     cprintf("\n%I64d\r",offs);     while (1) {         rv=_read(fh,buf,(unsigned int)__min(offs1-offs,MAX_CLU_BYTES));         if (rv==0) break;//         if (rv<0) {             printf("_read %s offset %I64d errno=%d %s\n",fullpath,offs,errno,strerror(errno));             fclose(fo);             _close(fh);             return 8;         }         wrv=fwrite(buf,1,rv,fo);         if (wrv!=rv) {             printf("fwrite %s errno=%d %s\n",ofn,errno,strerror(errno));             fclose(fo);             _close(fh);             return 9;         } else {             offs+=rv;             cprintf("%I64d\r",offs);             if (offs>=offs1) break;//         }     }     fclose(fo);     _close(fh);     printf("Copy %s offset %s to %s OK.\n",fullpath,argv[2],ofn);     return 0; }   至于CRC相关代码，参考7zip源代码相关片断。