我在C中实现了一个CRC32算法,但经过几个小时的环顾四周并尝试修复它,它仍然无效。它编译但校验和与几个在线CRC计算器不同。我怀疑错误是在行“if(0!=(character& j))”但不理解它,因为它甚至与维基百科上的代码基本相同。
int CRC32_C(char *message){
int length, i, j;
unsigned long p,g;
char character;
p = 0x00000000;
g = 0x04C11DB7;
length = strlen(message);
for (i = 0; i < length; i++){
character=*message;
//iterieren durch die bits jedes zeichens
for (j= 0x80; j != 0; j >>= 1){
//(p & 0x80000000)? 1 : 0)
if (0 != (character & j))
p = (p << 1) ^ g;
else
p <<=1;
}
message++;
}
return p;
}
//sample main
int main(char ** argv, int argc){
char *msg;
int p;
msg = "HALLO";
p = CRC32_C(msg);
printf("p ist 0x%x \n", p);
return 0;
}
示例输入:“HALLO”
预期结果:0x4E26F361(根据this page,使用相同的生成多项式,如页面底部所示)
实际结果:0xc25a747d
@chux:我尝试删除if子句中的“0!=”,但它没有改变结果。
CRC32_C仅代表“在C中实施”。正如Generator多项式所示,它是标准以太网。
感谢您的帮助
答案 0 :(得分:3)
CRC可以是msb到lsb或lsb到msb,并且生成多项式在在线示例中可以是不同的。 CRC32_F是msb到lsb,CRC32_R是lsb到msb(多项式反转)。如果您可以找到一个取十六进制的在线CRC计算器,请尝试使用十六进制01来测试msb到lsb,或使用十六进制80来测试lsb到msb。其他变化在计算crc之后将crc初始化为0xffffffff和/或反转(而不是)crc。查看以太网crc的描述,尝试使用CRC32_R,但将crc的初始化更改为crc = 0xfffffffful;
unsigned long CRC32_F(unsigned char *message, size_t length){
size_t i, j;
unsigned long crc,gnp;
crc = 0x00000000ul;
gnp = 0x04C11DB7ul;
for (i = 0; i < length; i++){
crc ^= ((unsigned long)*message)<<24;
for (j = 0; j < 8; j++){
if (crc & 0x80000000ul)
crc = (crc << 1) ^ gnp;
else
crc = (crc << 1);
}
message++;
}
return crc;
}
unsigned long CRC32_R(unsigned char *message, size_t length){
size_t i, j;
unsigned long crc,gnp;
crc = 0x00000000ul;
gnp = 0xEDB88320ul;
for (i = 0; i < length; i++){
crc ^= ((unsigned long)*message)<<0;
for (j = 0; j < 8; j++){
if (crc & 0x00000001ul)
crc = (crc >> 1) ^ gnp;
else
crc = (crc >> 1);
}
message++;
}
return crc;
}
答案 1 :(得分:0)
这将从HALLO生成CRC 0x4E26F361
:
#include <stddef.h>
#include <stdint.h>
/* CRC-32 (Ethernet, ZIP, etc.) polynomial in reversed bit order. */
#define POLY 0xedb88320
/* Compute CRC of buf[0..len-1] with initial CRC of crc. Start
with crc == 0. */
uint32_t crc32c(uint32_t crc, const unsigned char *buf, size_t len)
{
int k;
crc = ~crc;
while (len--) {
crc ^= *buf++;
for (k = 0; k < 8; k++)
crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
}
return ~crc;
}
以上计算CRC逐位,其中有更快的方法。这恰好是常用的CRC,因此您可以在zlib中找到一个名为crc32()
的快速实现,该实现在大多数系统中已作为已安装的库提供。