文档介绍:CRC-16/CRC-32程序代码不久前写一程序时要用到CRC-16,但找来找去只在UDDF里找到一个Delphi的CRC-32程序代码,而且是用查表法,虽然说查表法速度快,但256项32位数据我怀疑可能会有输入错误,让人不是那么放心,而我又不知道这个表是怎么算出来的。后来我又在一本两年前的笔记本里找到一段关于CRC的内容,也不知是从哪里抄来的,还好里面有一段程序代码,是CRC-16的,这段程序正是产生CRC表的,可是这区区几行的程序(基本上与下面的BuilderTable16函数相同)看得我一头雾水,直到这两天才弄明白,并据此推出CRC-32的算法,现将全部程序列在下面,并作一些说明以助于理解,不但要知其然,还要知其所以然嘛:补充:为了使这段程序更加实用,我将其整理为几个单元,分别用于Delphi和C++Builder。包括对数据流TMemoryStream和字符串的处理。可以在此下载:。-01//注意:因最高位一定为“1”,CRC_16=0x8005;//CRC-16=X16+X15+X2+ITT=0x1021;//ITT=X16+X12+X5+X0,CRC_32=0x04C10DB7;//CRC-32=X32+X26+X23+X22+X16+X11+X10+X8+X7+X5+X4+X2+X1+X0unsignedlongTable_CRC[256];//CRC表//构造16位CRC表voidBuildTable16(unsignedshortaPoly){unsignedshorti,j;unsignedshortnData;um;for(i=0;i<256;i++){nData=(unsignedshort)(i<<8);um=0;for(j=0;j<8;j++){if((nData^um)&0x8000)um=(um<<1)^aPoly;um<<=1;nData<<=1;}Table_CRC[i]=(unsignedlong)um;}}//计算16位CRC值,CRC-ITTunsignedshortCRC_16(unsignedchar*aData,unsignedlongaSize){unsignedlongi;um=0;CRC_16);//ITTfor(i=0;i<aSize;i++)um=(um<<8)^(unsignedshort)Table_CRC[(um>>8)^*aData++];um;}//构造32位CRC表voidBuildTable32(unsignedlongaPoly){unsignedlongi,j;unsignedlongnData;um;for(i=0;i<256;i++){nData=(unsignedlong)(i<<24);um=0;for(j=0;j<8;j++){if((nData^um)&0x80000000)um=(um<<1)^aPoly;um<<=1;nData<<=1;}Table_CRC[i]=um;}}//计算32位CRC-32值unsignedlongCRC_32(unsignedchar*aData,unsignedlongaSize){unsignedlongi;um=0;CRC_32);for(i=0;i<aSize;i++)um=(um<<8)^Table_CRC[(um>>24)^*aData++];um;}说明:CRC的计算原理如下(一个字节的简单例子)110110000000000000000000<-一个字节数据,左移16b^10001000000100001<-ITT多项式,17b--------------------------10100000001000010<-中间余数^10001000000100001-------------------------10100000110001100^10001000000100001-----------------------101000**********^10001000000100001---------------------10101101001010100^10001000000100001-------------------0100101001110101<-16bCRC仿此,可推出两个字节数据计算如下:d为数据,p为项式,a为余数dddddddddddddddd0000000000000000<-数据D(D1,D0,0,0)^ppppppppppppppppp<-多项式P-----------------------------------...aaaaaaaaaaaaaaaa0<-第一次的余数A'(A'1,A'0)^ppppppppppppppppp-