快速CRC算法?
Fast CRC algorithm?
我想用 ASCII 字符串创建一个 32 位数字。 CRC32 算法正是我要找的,但我不能使用它,因为它需要的 table 太大了(它适用于资源非常稀缺的嵌入式系统)。
那么:对快速而精简的 CRC 算法有什么建议吗?与原始 CRC32 相比,何时更可能发生冲突并不重要。
显然最大的查找 table 会带来最好的性能,但您可以使用任何(较小的)table 进行 16,8 或 4 位查找。
因此 table 大小适用于 crc32:
16bit-lookup: 4*2^16=256k
8bit-lookup: 4*2^8=1k
4bit-lookup: 4*2^4=64byte
4位table比16位table慢四倍。
您应该使用什么取决于您的速度要求。
正如 Luka Rahne 提到的,将 table 放入闪存是个好主意,但在许多平台上使用 const
关键字是不够的。
大多数情况下,您需要通过修改链接器命令文件将 table 放入闪存中的一个部分。
CRC 实现使用表格来提高速度。它们不是必需的。
这是使用 Castagnoli 多项式(与 Intel crc32 指令使用的相同)或以太网多项式(与 zip、gzip 等中使用的相同)的短 CRC32。
#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。您可以展开内部循环以提高速度,尽管您的编译器可能会为您这样做。
我想用 ASCII 字符串创建一个 32 位数字。 CRC32 算法正是我要找的,但我不能使用它,因为它需要的 table 太大了(它适用于资源非常稀缺的嵌入式系统)。
那么:对快速而精简的 CRC 算法有什么建议吗?与原始 CRC32 相比,何时更可能发生冲突并不重要。
显然最大的查找 table 会带来最好的性能,但您可以使用任何(较小的)table 进行 16,8 或 4 位查找。
因此 table 大小适用于 crc32:
16bit-lookup: 4*2^16=256k
8bit-lookup: 4*2^8=1k
4bit-lookup: 4*2^4=64byte
4位table比16位table慢四倍。
您应该使用什么取决于您的速度要求。
正如 Luka Rahne 提到的,将 table 放入闪存是个好主意,但在许多平台上使用 const
关键字是不够的。
大多数情况下,您需要通过修改链接器命令文件将 table 放入闪存中的一个部分。
CRC 实现使用表格来提高速度。它们不是必需的。
这是使用 Castagnoli 多项式(与 Intel crc32 指令使用的相同)或以太网多项式(与 zip、gzip 等中使用的相同)的短 CRC32。
#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。您可以展开内部循环以提高速度,尽管您的编译器可能会为您这样做。