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

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

这是我的function:

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

MD5哈希值是128位数。 因此,为了获得最佳性能,您应该保留所有128位。

鉴于您的函数将128位散列作为字符串,您需要将该字符串解析为一系列4个整数。 你的字符串可能看起来像这样:

 79054025255fb1a26e4bc422aef54eb4 

这是一个32字节的hex字符串。 如果是这样,您可以像这样提取二进制版本:

 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; 

您正在转换指针,即散列的地址 。 当然,该地址与散列值无关。

如何解决这个问题取决于你想要什么。 例如,您可以使用散列的最后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; } 

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

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

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

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

请注意, ab的值取决于计算机的字节顺序。 只要您不将散列发送到不同的架构就没关系。