Python 什么是更随机的,hashlib还是uradom?

Python 什么是更随机的,hashlib还是uradom?,python,random,hash,Python,Random,Hash,我和一个朋友在做一个项目,我们需要生成一个随机散列。在我们有时间讨论之前,我们都提出了不同的方法,因为他们使用不同的模块,我想问大家,如果有这样的事情,什么会更好 hashlib.sha1(str(random.random())).hexdigest() 或 把这个问题打出来让我觉得第二种方法更好。简单总比复杂好。如果您同意,这对于“随机”生成散列有多可靠?我如何测试这个 此解决方案: os.urandom(16).encode('hex') 是最好的,因为它可以生成可用于加密目的的随机性

我和一个朋友在做一个项目,我们需要生成一个随机散列。在我们有时间讨论之前,我们都提出了不同的方法,因为他们使用不同的模块,我想问大家,如果有这样的事情,什么会更好

hashlib.sha1(str(random.random())).hexdigest()

把这个问题打出来让我觉得第二种方法更好。简单总比复杂好。如果您同意,这对于“随机”生成散列有多可靠?我如何测试这个

此解决方案:

os.urandom(16).encode('hex')
是最好的,因为它可以生成可用于加密目的的随机性(取决于操作系统实现)

random.random()
生成


散列一个随机值不会增加任何新的随机性。

测试随机性是出了名的困难-然而,我会选择第二种方法,但在这种情况下,散列是由一个随机数播种的(或者,仅在脑海中)

散列的全部要点是创建一个基于输入的细微差异而大不相同的数字。对于您的用例,输入的随机性应该可以。然而,如果您想要散列一个文件并检测一个字节的差异,那么散列算法就会发挥作用

不过,我只是好奇:为什么要使用哈希算法呢?看起来你在寻找一个纯粹的随机数,而且有很多生成uuid的库,它们比随机数生成器具有更强的唯一性保证。

random.random()
是一个伪radmom生成器,这意味着数字是从序列生成的。如果调用
random.seed(一些数字)
,那么之后生成的序列将始终相同

os.uradom()
从操作系统的rng中获取随机数,rng使用熵池收集真实的随机数,通常通过硬件设备的随机事件,对于生成大量随机数的系统,甚至存在特殊的随机熵生成器

在unix系统上,传统上有两个随机数生成器:
/dev/random
/dev/urandom
。如果没有足够的可用熵,则调用第一个块,而当您读取
/dev/uradom
并且没有足够的可用熵数据时,它使用伪rng并且不阻塞


因此,使用通常取决于您需要什么:如果您需要几个均匀分布的随机数,那么内置的prng就足够了。对于加密应用,最好使用实数随机数。

第二种解决方案显然比第一种解决方案具有更多的熵。假设
os.urandom
random.random
的随机位源的质量相同:

  • 在第二种解决方案中,您将获取16字节=128位的随机性
  • 在第一个解决方案中,您获取的浮点值具有大约52位的随机性(IEEE 754双,忽略子正规数等)。然后把它散列,当然,这不会增加任何随机性

更重要的是,来自
os.urandom
的随机性的质量预计和记录要比来自
random.random
的随机性好得多
os.uradom
的docstring说“适合加密使用”。

如果您需要唯一标识符(uuid),那么应该使用

import uuid
uuid.uuid4().hex

这些都是非常好的答案。谢谢。@greengit:上面的小片段很可能是针对Python2.x版本(未在3.x中测试)的,这通常是正确的,除非在少数情况下,包括新启动的系统缺少生成高质量随机数的随机性池(熵),或者当池被大量调用耗尽时(因为我不是专家,所以不要问多大)。攻击者也可以利用后者使随机性更可预测(例如,创建大量需要随机盐的帐户)。因此,除非您需要一个加密安全的随机数,否则您应该避免使用
os.urandom
,并确保在使用时它不会被滥用。请注意,python的random.SystemRandom[1]类提供了与random相同的api接口。*同时依赖于urandom。[1]@CristopheD:try
base64.b64encode(os.urandom(16))
import uuid
uuid.uuid4().hex