【问题标题】:Whats more random, hashlib or urandom?什么更随机,hashlib 或 urandom?
【发布时间】:2012-05-07 15:21:19
【问题描述】:

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

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

os.urandom(16).encode('hex')

输入这个问题让我觉得第二种方法更好。简单胜于复杂。如果您同意,这对于“随机”生成哈希有多可靠?我将如何测试这个?

【问题讨论】:

    标签: python random hash


    【解决方案1】:

    这个解决方案:

    os.urandom(16).encode('hex')
    

    是最好的,因为它uses the OS 生成随机性,应该可用于加密目的(取决于操作系统实现)。

    random.random() 生成 pseudo-random values

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

    【讨论】:

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

    random.random() 是一个伪 radmom 生成器,这意味着数字是从一个序列中生成的。如果你调用random.seed(some_number),那么之后生成的序列总是一样的。

    os.urandom() 从 os 的 rng 中获取随机数,它使用熵池来收集真正的随机数,通常通过来自硬件设备的随机事件,甚至存在用于具有大量随机数的系统的随机特殊熵生成器已生成。

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

    所以使用通常取决于您需要什么:如果您需要一些均匀分布的随机数,那么内置的 prng 应该就足够了。对于加密用途,使用实数随机数总是更好。

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

        测试随机性是出了名的困难 - 但是,我会选择第二种方法,但仅在这种情况下(或者,仅在想到的情况下),其中哈希是由随机数播种的。

        哈希的全部意义在于根据输入的细微差异创建一个截然不同的数字。对于您的用例,输入的随机性应该可以。但是,如果您想对文件进行哈希处理并检测一个 eensy 字节的差异,那就是哈希算法大放异彩的时候了。

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

        【讨论】:

          【解决方案5】:

          如果你想要一个唯一标识符(uuid),那么你应该使用

          import uuid
          uuid.uuid4().hex
          

          https://docs.python.org/3/library/uuid.html

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-09-01
            • 1970-01-01
            • 2017-06-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-19
            相关资源
            最近更新 更多