2011-10-08 16 views
17

私は長い単語のリストを持っており、それらをハッシュしたいと思います。良いハッシュ関数は何でしょうか?これまでの私のハッシング関数は、文字のASCII値を合計し、次にテーブルサイズをモジュロにします。私は効率的でシンプルなものを探しています。英語の単語にはどのような良いハッシュ関数がありますか?

+0

ここでチェックします。http://www.cse。 yorku.ca/~oz/hash.html –

+0

[文字列のための良いハッシュ関数](https://stackoverflow.com/questions/2624192/good-hash-function-for-strings)と[何が良いJavaの64ビットハッシュ関数文字列?](https://stackoverflow.com/questions/1660501/what-is-a-good-64bit-hash-function-in-java-for-textual-strings) –

答えて

15

単純に文字を合計するのは良い方法ではありません。なぜなら、置換によって同じ結果が得られるからです。

この文字列(djb2)は非常に一般的で、ASCII文字列でうまく機能します。

unsigned long hashstring(unsigned char *str) 
{ 
    unsigned long hash = 5381; 
    int c; 

    while (c = *str++) 
     hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ 

    return hash; 
} 

さらに多くの代替手段と性能指標が必要な場合は、hereをお読みください。

を追加しました:これらの入力領域が事前に知られていない一般ハッシュ関数、です(おそらくいくつかの非常に一般的な仮定を除いては:例えば、ASCII入力でわずかに優れ上記作品)最も一般的なシナリオがあり、 。あなたが既知の制限されたドメイン(固定入力のセット)を持っているなら、Fionnの答えを見てください。

+0

5381はテーブルサイズですか? –

+0

いいえ、単なる「種」です。 – leonbloy

+1

@MikeG:これは「シード」または開始値です。これは一般に「Times 33」ハッシュとして知られています。 – user7116

6

たぶん、このようなものはあなたを助けるでしょう:http://www.gnu.org/s/gperf/

これは、入力ドメインのための最適化されたハッシュ関数を生成します。

6

暗号が安全である必要がない場合は、Murmur Hashをお勧めします。それは非常に速く、拡散が大きい。使いやすい。

http://en.wikipedia.org/wiki/MurmurHash

http://code.google.com/p/smhasher/wiki/MurmurHash3

あなたが暗号的に安全なハッシュを必要とした場合は、その後、私は、OpenSSLを経由してSHA1を示唆しています。

http://www.openssl.org/docs/crypto/sha.html

+0

+1 MurmurHash、do CityHashとMurmurHashを比較すると分かりますか?私は両方について良いことを聞いたことがありますが、包括的な比較を見たことはない、ちょうどいくつかの逸話的な事実を持っていた。 –

2
少し遅れ

が、ここでは32ビット版のために良いとして、以下の64ビット版のための非常に低い衝突率を持つハッシュ関数である、と〜ほとんど〜:

uint64_t slash_hash(const char *s) 
//uint32_t slash_hash(const char *s) 
{ 
    union { uint64_t h; uint8_t u[8]; }; 
    int i=0; h=strlen(s); 
    while (*s) { u[i%8] += *s + i + (*s >> ((h/(i+1)) % 5)); s++; i++; } 
    return h; //64-bit 
    //return (h+(h>>32)); //32-bit 
} 

ハッシュ番号もまた、可能な範囲に非常に均等に分散しています。検出できないほどの塊はありません。これはランダムな文字列のみを使用してチェックされています。

64ビットの衝突が0で、32ビットの衝突が1つのLibreOffice辞書/シソーラス語(英語とフランス語 - 97000を超える単語と構造体)と組み合わせたローカルテキストファイルから抽出された単語に対してもテストされています。 )

(また同じセットのFNV1A_Hash_Yorikke、djb2とMurmurHash2と比較:Yorikke & djb2はうまくやっていなかった。slash_hashは、すべてのテストにMurmurHash2よりもわずかに良いやった)

+0

これは合理的なハッシュ関数です。私は無名の組合を避けることを提案する。 - >> 'union {uint64_t h; uint8_t u [8];コード内の同様の変更 - >> 'uu.h = strlen(s);' ... 'uu.u [i%8] + = ...'等 – joop

関連する問題