将32位MD5字符串转换为整数

15

如何以最有效的方式将MD5哈希转换为唯一整数并执行模操作?


你想做哈希 % x 还是 x % 哈希?在第一种情况下,你甚至可能不需要整个哈希来计算答案。 - Joren
我正在寻找哈希 % X。 - ensnare
这些答案中有没有对您有所帮助,还是您需要更多的见解? - Noctis Skytower
5个回答

30

由于没有指定解决方案语言,因此本例使用Python。

import os
import hashlib

array = os.urandom(1 << 20)
md5 = hashlib.md5()
md5.update(array)
digest = md5.hexdigest()
number = int(digest, 16)

print(number % YOUR_NUMBER)

MD5是128位的信息。Python中的int通常是32或64位的信息,因此转换为int会丢失数据,不是吗?我认为你需要使用long。 - elhefe
为什么要将它转换为16进制?这是惯例吗? - Nate
@Nate hexdigest 方法很方便使用。通过调用 int 函数,将其返回的字符串转换为数字同样也很容易实现。 - Noctis Skytower
@NoctisSkytower 感谢您的回复 - 我不是在询问 hexdigestint 的区别,而是关于基数16与基数10或基数2之类的问题。我尝试了几种不同的选项,似乎哈希值将转换为一个以16为底或更高的整数,但我并不真正理解为什么会这样。 - Nate
@Nate 让我们谈谈计算机理论(对或错)。在计算机中,整数以位的形式存储(基于2进制)。然而,它们存储的基本不如整数所代表的无基础值重要。当您想查看一个整数时,可以使用任何字符以任何基数显示它。在许多情况下,您可以忘记数字的基数,只考虑其值。如何表达该值取决于您所思考的基数或您想要用哪种基数显示它,但是数学的基本原理几乎不受数字基数的影响。 - Noctis Skytower
非常感谢 - 非常有帮助! - Nate

3

您没有说明运行的平台以及哈希值的格式。可能是十六进制,因此您有16个字节的信息。

为了将其转换为一个唯一的整数,您基本上需要一个16字节(128位)的整数类型。许多平台没有这样的类型可用,但在C#或Java中可以使用两个长整型值,或在Java或.NET 4.0中使用BigInteger

从概念上讲,您需要将十六进制字符串解析为字节,然后将字节转换为整数(或两个整数)。最有效的方法完全取决于您使用的平台。


1
您可以查看 PHP 中的 sscanf 函数:http://au.php.net/manual/zh/function.sscanf.php - Matthew Scharley

2

MD5中的数据量超过了一个64位整数所能容纳的范围,因此没有办法(除非知道您使用的平台)获得唯一的整数。您可以通过将十六进制版本转换为几个整数的数据,然后将它们组合起来(加法或乘法)来获得相对唯一的整数。如何进行这样的操作取决于您使用的语言。

许多编程语言都会实现unpacksscanf函数,这是一个很好的起点。


2
你假设“整数”仅限于64位。那么BigInteger呢? - Jon Skeet
1
当然,但很多平台都没有任意长度的整数。是否有(本地)BigInteger实现完全取决于您所在的平台。 - Matthew Scharley
2
当然可以,但“这取决于你的平台”并不等同于“没有办法” :) - Jon Skeet

2
如果您仅需要模数,实际上无需将其转换为128字节的整数。 您可以像这样逐位或逐字节进行操作。
mod=0
for(i=0;i<32;i++)
{
   digit=md5[i]; //I presume you can convert chart to digit yourself.
   mod=(mod*16+digit) % divider;
}

1

您需要定义自己的哈希函数,将MD5字符串转换为所需宽度的整数。如果您想将MD5哈希解释为普通字符串,则可以尝试FNV算法。它非常快速且分布相当均匀。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接