2

私の目標は、MD5結果の結果を使用してハッシュテーブルにインデックスを付けることです。テーブル内の適切なスロットを見つけるために、モジュロ演算を実行したいと思います。unsignedlonglong型としてキャストしてみました。結果を印刷したとき、同じMD5ハッシュに対して毎回異なる番号を取得しました。MD5ハッシュは、最初はunsignedchar*です。誰かが私が間違っていることを教えてもらえますか?

これが私の関数です:

int get_fp_slot(unsigned char * fingerprint, int size)
{
return (unsigned long long)fingerprint % size;
}
4

3 に答える 3

2

MD5ハッシュは128ビットの数値です。したがって、最高のパフォーマンスを得るには、おそらくすべての128ビットを保持する必要があります。

関数が128ビットハッシュを文字列として受け取るとすると、その文字列を一連の4つの整数に解析する必要があります。文字列はおそらく次のようになります。

79054025255fb1a26e4bc422aef54eb4

これは32バイトの16進文字列です。その場合、次のようにバイナリバージョンを抽出します。

int v1, v2, v3, v4;
sscanf( &fingerprint[0], "%x", &v1 );
sscanf( &fingerprint[8], "%x", &v2 );
sscanf( &fingerprint[16], "%x", &v3 );
sscanf( &fingerprint[24], "%x", &v4 );

あなたが今何をするかは、あなたがあなたのハッシュをどれだけ良くしたいかに本当に依存します。本当に32ビットの数値を使用する必要がある場合は、それらすべての数値をXORするだけです。

int hash = v1 ^ v2 ^ v3 ^v4;
于 2012-06-24T18:34:13.523 に答える
1

ポインタ、つまりハッシュのアドレスをキャストしています。もちろん、そのアドレスはハッシュの値とは無関係です。

それを修正する方法はあなたが望むものに依存します。たとえば、ハッシュの最後の16バイトを使用して、それを解析してunsigned long long

// sanity and error checking omitted for brevity
int get_fp_slot(unsigned char *fingerprint, int size)
{
    size_t len = strlen(fingerprint);
    size_t offset = len < 16 ? 0 : len-16;
    unsigned long long hash_tail = strtoull(fingerprint + offset,NULL,16);
    return hash_tail % size;
}

またはモジュロを段階的に実行します

// uses a helper hex_val that converts a hexadecimal digit to the integer it signifies
int get_fp_slot(unsigned char *fingerprint, int size)
{
    unsigned long long hash_mod = 0;
    while(*fingerprint) {
        hash_mod = (16*hash_mod + hex_val(*fingerprint)) % size;
        ++fingerprint;
    }
    return hash_mod;
}
于 2012-06-24T18:37:03.663 に答える
0

コードでは、MD5値を形成するバイトではなく、ポインター自体を変換しています。

MD5は128ビット、つまり16バイトです。long longタイプが64ビット(8バイト)であると仮定すると、それを2つのlong long値として表すことができ、それらをXORしてハッシュを取得できます。または、必要に応じて、そのうちの1つを選択することもできます...ハッシュ品質はおそらく同様です。

あなたはそれを言わないが、私はあなたの指紋がMD5値を持つ16バイトの配列へのポインタであると仮定している。それで:

unsigned long long a = *(unsigned long long*)fingerprint;
unsigned long long b = *(unsigned long long*)(fingerprint + 8);
return a ^ b;

aとの値は、bマシンのエンディアンに依存することに注意してください。ハッシュを別のアーキテクチャに送信しない限り、問題はありません。

于 2012-06-24T18:39:12.430 に答える