ASCII文字列から32ビットの数値を作成したいのですが。 CRC32アルゴリズムはまさに私が探しているものですが、必要なテーブルが非常に大きいため、それを使用することはできません(リソースが非常にまれな組み込みシステム用です)。
だから:高速でスリムなCRCアルゴリズムの提案はありますか?衝突が元のCRC32の場合よりも少し確率が高い場合は問題ではありません。
ありがとう!
CRCの実装では、速度を上げるためにテーブルを使用します。それらは必要ありません。
Castagnoli多項式(Intel crc32命令で使用されるものと同じもの)またはEthernet多項式(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を更新するために、データのチャンクで連続して呼び出すことができます。コンパイラーが自動で実行する場合もありますが、速度を上げるために内部ループを展開できます。
明らかに、最大のルックアップテーブルが最高のパフォーマンスをもたらしますが、16、8、または4ビットのルックアップには任意の(小さい)テーブルを使用できます。
したがって、テーブルサイズはcrc32用です。
16bit-lookup: 4*2^16=256k
8bit-lookup: 4*2^8=1k
4bit-lookup: 4*2^4=64byte
4ビットテーブルは、16ビットテーブルよりも4倍遅くなります。
使用する必要があるものは、速度要件によって異なります。
Luka Rahneが述べているように、フラッシュメモリにテーブルを置くことは良い考えですが、多くのプラットフォームではconst
キーワードを使用するだけでは十分ではありません。
ほとんどの場合、リンカーコマンドファイルを変更して、テーブルをフラッシュに配置されたセクションに配置する必要があります。