快速CRC算法?

时间:2015-01-14 09:44:45

标签: c++ c crc crc32

我想用ASCII字符串创建一个32位数字。 CRC32算法正是我正在寻找的,但是我不能使用它,因为它需要的表太大了(它适用于资源非常少的嵌入式系统)。

那么:对快速而纤薄的CRC算法的任何建议?如果碰撞比原始CRC32更可能,那么无关紧要。

谢谢!

2 个答案:

答案 0 :(得分:24)

CRC实现使用表来提高速度。它们不是必需的。

这是一个简短的CRC32,使用Castagnoli多项式(与Intel crc32指令使用的相同)或以太网多项式(与zip,gzip等中使用的相同)。

#include <stddef.h>
#include <stdint.h>

/* CRC-32C (iSCSI) polynomial in reversed bit order. */
#define POLY 0x82f63b78

/* CRC-32 (Ethernet, ZIP, etc.) polynomial in reversed bit order. */
/* #define POLY 0xedb88320 */

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。您可以展开内部循环以获得速度,不过您的编译器可能会为您执行此操作。

答案 1 :(得分:0)

显然,最大的查找表将带来最佳性能,但您可以使用任何(较小的)表进行16,8或4位查找。

因此表格大小适用于crc32:

16bit-lookup: 4*2^16=256k  
 8bit-lookup: 4*2^8=1k  
 4bit-lookup: 4*2^4=64byte  

4位表比16位表慢四倍 你应该使用什么取决于你的速度要求。

正如Luka Rahne所说,将表格放入闪存是一个好主意,但在许多平台上使用const关键字是不够的。
通常,您需要通过修改链接器命令文件将表放入闪存中的部分。