在对CRC-32算法进行一些研究之后,我得到了以下内容:
/* Usage: Recursively call this with previous crc. Start with crc = 0. */
#define POLYNOMIAL 0x04C11DB7
unsigned int crc32( unsigned int crc, char* msg, unsigned int len ) {
for ( unsigned int byteNum = 0; byteNum < len; byteNum++ ) {
char msgByte = msg[ byteNum ];
for ( unsigned int bitNum = 0; bitNum < 8; bitNum++ ) {
char msgBit = ( msgByte >> ( 7 - bitNum ) ) & 0x1;
if ( ( crc & 0x80000000 ) != 0 )
crc = ( ( crc << 1 ) | msgBit ) ^ POLYNOMIAL;
else
crc = ( crc << 1 ) | msgBit;
}
}
return crc;
}
然而,我的代码输出完全不同于常用的CRC-32功能(用表优化)
现在我希望有人可以给我一些CRC-32算法的示例源代码,它不是通过表格优化的,并且可以很好地了解它的实际工作原理。
谢谢,
丹尼斯
答案 0 :(得分:1)
CRC-32算法将输入视为基数2中的大多数。每个输入位是x的一个幂的系数。例如,最后一位是x ^ 0的系数,最后一位是x ^ 1的系数,依此类推。
该多项式除以生成多项式,其具有度32(即,最高幂是x ^ 32)。所有计算都在场GF(2)上的多项式环中进行。使用中有不同的生成多项式,因此实际上不存在一种CRC-32算法。它们在其他方面也有所不同(例如位顺序)。
CRC-32值是该多项式除法的余数,是多数度为31的多项式,再次由其系数的位表示。
答案 1 :(得分:1)
这看起来不对:
if ( ( crc & 0x80000000 ) != 0 )
crc ^= POLYNOMIAL;
crc = ( crc << 1 ) | msgBit;
你需要在移位之前测试crc
高位,但是在移位并插入消息位之后,对其余的POLYNOMIAL 进行测试。
请注意,实际多项式为0x104C11DB7
,并且位32中的1取消0x80000000 << 1
(测试证明已设置)
答案 2 :(得分:1)
在档案馆等中使用的那个看起来像这样:
char msg[] = "hello, world!";
uint POLY = 0xEDB88320;
int main( void ) {
uint i,j,l,x;
l = sizeof(msg)-1;
x = 0;
for( i=0; i<l; i++ ) {
x = x ^ msg[i];
for( j=0; j<8; j++ ) {
x = (x>>1) ^ 0x80000000 ^ ((~x&1)*POLY);
}
}
printf( "crc32(\"%s\")=%08X\n", msg, x );
}
或者
x = 0;
for( i=0; i<l; i++ ) {
x = x ^ (msg[i]^0xFF);
for( j=0; j<8; j++ ) {
x = (x>>1) ^ ((x&1)*POLY);
}
x ^= 0xFF000000;
}
答案 3 :(得分:1)
答案 4 :(得分:0)
我偶然发现以下pdf:stigge.org/martin/pub/SAR-PR-2006-05.pdf
第18页包含我的解决方案。
由于一些奇怪的原因,我转移到了错误的一边,多项式应该反转。
这是给出正确输出的代码:
/* Usage: Recursively call this with previous crc. Start with crc = 0. */
#define POLYNOMIAL 0xEDB88320
unsigned int crc32( unsigned int crc, char* msg, unsigned int len ) {
crc ^= 0xFFFFFFFF;
for ( unsigned int byteNum = 0; byteNum < len; byteNum++ ) {
char msgByte = msg[ byteNum ];
for ( unsigned int bitNum = 0; bitNum < 8; bitNum++ ) {
if ( ( crc ^ msgByte ) & 1 )
crc = ( crc >> 1 ) ^ POLYNOMIAL;
else
crc >>= 1;
msgByte >>= 1;
}
}
return crc ^ 0xFFFFFFFF;
}