将MD5结果转换为C中的整数

时间:2012-06-24 18:18:40

标签: c casting md5

我的目标是使用MD5结果的结果来索引哈希表。我想对它执行Modulo操作以在表中找到适当的插槽。我已经尝试将它作为无符号长long类型进行投射。当我打印结果时,我每次都获得相同的MD5哈希值。 MD5哈希最初是unsigned char *。有人能告诉我我做错了吗?

这是我的功能:

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

3 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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;
}

答案 2 :(得分:0)

在您的代码中,您正在转换指针本身,而不是转换形成MD5值的字节!

MD5是128位,即16字节。假设您的long long类型是64位(8字节),您可以将其表示为两个long long值,然后将它们XOR以获取哈希值。或者如果你愿意,你可以简单地选择其中一个...哈希质量可能类似。

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

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

请注意,ab的值取决于计算机的字节顺序。只要你不将散列发送到不同的架构就无所谓了。