2

我的目标是使用 MD5 结果的结果来索引哈希表。我想对其执行模运算以在表中找到适当的插槽。我尝试将其转换为无符号长长类型。当我打印结果时,对于相同的 MD5 哈希,我每次都会得到一个不同的数字。MD5 哈希最初是一个无符号字符 *。有人可以告诉我我做错了什么吗?

这是我的功能:

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 字节的十六进制字符串。如果是这样,您可以像这样提取二进制版本:

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 位数字,那么只需将所有这些数字异或:

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 字节),您可以将其表示为两个long long值,然后对它们进行异或运算以获取哈希值。或者,如果您愿意,您可以简单地选择其中之一……哈希质量可能相似。

您没有说出来,但我假设您的指纹是指向具有 MD5 值的 16 字节数组的指针。然后:

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

请注意, 和 的值ab取决于您机器的字节序。只要您不将散列发送到不同的架构,这并不重要。

于 2012-06-24T18:39:12.430 回答