我想用ASCII字符串创建一个32位数字。 CRC32算法正是我正在寻找的,但是我不能使用它,因为它需要的表太大了(它适用于资源非常少的嵌入式系统)。
那么:对快速而纤薄的CRC算法的任何建议?如果碰撞比原始CRC32更可能,那么无关紧要。
谢谢!
答案 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
关键字是不够的。
通常,您需要通过修改链接器命令文件将表放入闪存中的部分。