【问题标题】:Whats the difference between os.urandom() and random?os.urandom() 和 random 有什么区别?
【发布时间】:2018-05-10 21:55:52
【问题描述】:

在随机模块 python page (Link Here) 上有这个警告:

警告:此模块的伪随机生成器不应用于安全目的。如果您使用 os.urandom() 或 SystemRandom 需要一个加密安全的伪随机数生成器。

  • 那么 os.urandom() 和 random 有什么区别呢?

  • 一个比另一个更接近真正的随机?

  • 安全随机在非加密实例中是否会过度杀伤?

  • python中还有其他随机模块吗?

【问题讨论】:

  • python 3 中有一个模块:secrets,它为密码学设计的。
  • crypto.stackexchange 上也有一个答案:crypto.stackexchange.com/questions/39186/…
  • @quamrana 我的问题与密码学无关。我想知道 python-2.7 中两个随机模块之间的区别,一个恰好用于密码学
  • @quamrana 我可以看出你很困惑,我的问题的标题很混乱,并不代表我的问题

标签: python python-2.7 random


【解决方案1】:

您可以阅读加密安全 RNG in this fantastic answer over at Crypto.SE 的区别。

random 和像urandom 这样的系统 RNG 之间的主要区别是用例之一。 random 实现确定性 PRNG。有些场景正是您想要的。例如,当您有一个带有要测试的随机元素的算法时,您需要这些测试是可重复的。在这种情况下,您需要一个可以播种的确定性 PRNG。

另一方面,urandom 无法播种,并从许多不可预测的来源中获取熵源,使其更加随机

真正随机是另外一回事,你需要一个随机的物理源,比如测量原子衰变的东西;这在物理意义上确实是随机的,但对于大多数应用程序来说通常是多余的。

【讨论】:

    【解决方案2】:

    那么 os.urandom() 和 random 有什么区别呢?

    随机本身是可预测的。这意味着给定相同的种子,随机生成的数字序列是相同的。查看this question 以获得更好的解释。 This question 也说明了随机并不是真正的随机。

    大多数编程语言通常都是这种情况——随机数的生成并不是真正随机的。您可以在以下情况下使用这些数字 加密安全不是问题,或者如果您希望生成相同的数字模式。

    一个比另一个更接近真正的随机吗?

    不知道如何回答这个问题,因为无法生成真正的随机数。请查看this articlethis question 了解更多信息。

    由于 random 生成可重复的模式,我会说 os.urandom() 肯定更“随机”

    安全随机在非加密实例中是否会过大?

    我写了以下函数,似乎没有很大的时差。但是,如果您不需要加密安全号码 使用os.urandom() 真的没有意义。再次归结为用例,你想要一个可重复的模式,你想要你的数字有多“随机”等等?

    import time
    import os
    import random
    
    
    def generate_random_numbers(x): 
      start = time.time()
      random_numbers = []
      for _ in range(x):
        random_numbers.append(random.randrange(1,10,1))
      end = time.time()
      print(end - start)
    
    
    def generate_secure_randoms(x):
      start = time.time()
      random_numbers = []
      for _ in range(x):
        random_numbers.append(os.urandom(1))
      end = time.time()
      print(end - start)
    
    
    generate_random_numbers(10000)
    generate_secure_randoms(10000)
    

    结果:

    0.016040563583374023
    0.013456106185913086
    

    python中还有其他随机模块吗?

    Python 3.6 引入了新的secrets module

    【讨论】:

      【解决方案3】:

      random 实现了一个伪随机数生成器。知道了算法和参数,我们可以预测生成的序列。文末是linear pseudo random generator 在 Python 中的一个可能实现,它表明生成器可以是一个简单的线性函数。

      os.urandom 使用系统熵源进行更好的随机生成。熵源是我们无法预测的,例如异步事件。例如,我们无法预测我们敲击键盘键的频率。 来自其他设备的中断也可能是不可预测的。

      random 模块中有一个类:SystemRandom,它使用 os.urandom() 来生成随机数。

      实际上,无法证明给定序列是随机的还是非随机的。 Andrey Kolmogorovwork this out 广泛存在于 1960 年代左右。 当在任何给定语言中获取序列的规则大于序列本身时,可以认为序列是随机的。以下面的序列为例,它看起来是随机的:

      264338327950288419716939937510

      但是我们也可以将其表示为:

      pi 数字 21 到 50

      由于我们找到了一种方法来表示比序列本身更小的序列,因此序列不是随机的。我们甚至可以想出一种更紧凑的语言来表示它,比如:

      pi[21,50]

      或者另一个。

      但是用最紧凑的语言(或者更小的算法,如果你愿意的话)生成序列的更小的规则可能永远不会被发现,即使它存在。 这一发现仅取决于人类的智力,这不是绝对的。 可能有一种确定的方法来证明一个序列是否是随机的,但我们只有在有人找到它时才能知道它。或者也许没有办法证明随机性是否存在。

      LCG(线性全等生成器)在 Python 中的实现可以是:

      from datetime import datetime
      
      class LCG:
          defaultSeed       = 0
          defaultMultiplier = 1664525
          defaultIncrement  = 1013904223
          defaultModulus    = 0x100000000
      
          def __init__(self, seed, a, c, m):
              self._x0 = seed  #seed
              self._a  = a     #multiplier
              self._c  = c     #increment
              self._m  = m     #modulus
          
          @classmethod
          def lcg(cls, seed = None):
              if seed is None: seed = cls.defaultSeed
              return LCG(int(seed), cls.defaultMultiplier, 
                         cls.defaultIncrement, cls.defaultModulus)
      
          #pre: bound > 0   
          #returns: pseudo random integer in [0, bound[
          def randint(self, bound):
              self._x0 = (self._a * self._x0 + self._c) % self._m
              return int(abs(self._x0 % bound))
      
      
      #generate a sequence of 20 digits
      rnd = LCG.lcg(datetime.now().timestamp()) #diff seed every time
      for i in range(20):
          print(rnd.randint(10), end='')
      print()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-02
        • 2011-12-12
        • 2010-09-16
        • 2012-03-14
        相关资源
        最近更新 更多