2015-01-14 12 views
5

ASCII文字列のうち32ビットの数値を作成したいとします。 CRC32アルゴリズムはまさに私が探しているものですが、必要なテーブルが非常に巨大なので(ressourcesが非常にまれな組み込みシステム用です)、使用できません。高速CRCアルゴリズム?

So:高速でスリムなCRCアルゴリズムの提案はありますか?コリジョンが元のCRC32よりも多少発生する可能性はありません。

ありがとうございます!

+7

CRC32は、ルックアップテーブルなしで実装することも、必要な場合は1kバイトのルックアップテーブルを使用して実装することもできます。 http://wiki.osdev.org/CRC32の例。バイトをセーブする必要がある場合は、adler32を使用してください。 – dascandy

+2

'ressourcesの意味は非常にまれですか? 64MB未満、8KB未満または512バイト未満? – jeb

+0

jeb:非常にまれであるということは、現時点では、http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/libkern/crc32.cに示すように、テーブルを追加するのに十分なスペースがないことを意味します。 – Elmi

答えて

16

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を更新するためにデータのチャンクで連続的に呼び出すことができます。あなたのコンパイラはあなたのためにそれを行うかもしれませんが、スピードのために内部ループを展開することができます。

+1

@HolyBlackCat:なぜですか?これは、CRCを計算するための一般的なイディオムです。これまでに計算されたCRCを渡し、更新されたCRC値を返します。 –

+0

また、これは非常に効率的にコンパイルされ、引き数が来て、返される値は同じレジスタに残って決して残らない。 –

+0

@MichaelBurrなぜ私は3年前に私が古いと言いましたか分かりません。 :/ – HolyBlackCat

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ビットのテーブルよりも4倍遅いです。
使用する必要があるのは、速度要件によって異なります。

Luka Rahneは、フラッシュメモリにテーブルを置くことをお勧めしますが、多くのプラットフォームではconstキーワードを使用するだけでは十分ではありません。
ほとんどの場合、リンカーコマンドファイルを変更して、フラッシュに配置されたセクションにテーブルを配置する必要があります。

関連する問題