编程语言
首页 > 编程语言> > Python:random.random()植入哪里?

Python:random.random()植入哪里?

作者:互联网

说我有一些python代码:

import random
r=random.random()

r的值一般从哪里来?
如果我的操作系统没有随机数,那么它将在哪里播种呢?
为什么不建议将其用于加密?有什么方法可以知道随机数是多少?

解决方法:

遵循da代码.

要查看随机模块在系统中的“位置”,您可以在终端中执行以下操作:

>>> import random
>>> random.__file__
'/usr/lib/python2.7/random.pyc'

这为您提供了.pyc(“已编译”)文件的路径,该文件通常与可以找到可读代码的原始.py并排放置.

让我们看看/usr/lib/python2.7/random.py中发生了什么:

您会看到它创建了Random类的实例,然后(在文件底部)“将该”实例的方法“提升”为模块函数.整洁的把戏.当将随机模块导入任何地方时,将创建该Random类的新实例,然后初始化其值,并将方法重新分配为模块的功能,从而使其在每次导入时都相当随机(erm …或每个Python解释器实例)的基础.

_inst = Random()
seed = _inst.seed
random = _inst.random
uniform = _inst.uniform
triangular = _inst.triangular
randint = _inst.randint

此Random类在其__init__方法中所做的唯一事情是将其作为种子:

class Random(_random.Random):
    ...
    def __init__(self, x=None):
        self.seed(x)    
...
_inst = Random()
seed = _inst.seed

所以…如果x为None(未指定种子)会发生什么?好吧,让我们检查一下self.seed方法:

def seed(self, a=None):
    """Initialize internal state from hashable object.

    None or no argument seeds from current time or from an operating
    system specific randomness source if available.

    If a is not None or an int or long, hash(a) is used instead.
    """

    if a is None:
        try:
            a = long(_hexlify(_urandom(16)), 16)
        except NotImplementedError:
            import time
            a = long(time.time() * 256) # use fractional seconds

    super(Random, self).seed(a)
    self.gauss_next = None

注释已经说明发生了什么.此方法尝试使用操作系统提供的默认随机数生成器,如果没有,则将使用当前时间作为种子值.

但是,等等… _urandom(16)到底是什么鬼东西?

好吧,答案就在这个random.py文件的开头:

from os import urandom as _urandom
from binascii import hexlify as _hexlify

Tadaaa …种子是一个来自os.urandom的16字节数字

假设我们使用的是文明的操作系统,例如Linux(带有真实的随机数生成器). random模块使用的种子与执行操作相同:

>>> long(binascii.hexlify(os.urandom(16)), 16)
46313715670266209791161509840588935391L

之所以认为指定种子值不是那么好,是因为随机函数并不是真正的“随机”……它们只是一个非常奇怪的数字序列.但是给定相同的种子,该序列将是相同的.您可以自己尝试:

>>> import random
>>> random.seed(1)
>>> random.randint(0,100)
13
>>> random.randint(0,100)
85
>>> random.randint(0,100)
77

无论何时,如何运行,甚至在哪里运行该代码(只要用于生成随机数的算法保持不变),如果您的种子为1,您将始终获得整数13、85、77 …某种程度上打败了目的(关于伪随机数生成,请参见this)另一方面,尽管有use cases,但实际上这可能是理想的功能.

这就是为什么依赖操作系统随机数生成器被认为“更好”的原因.这些通常是根据硬件中断来计算的,硬件中断是非常非常随机的(其中包括用于读取硬盘驱动器的interruptions,由人类用户键入的击键,四处移动鼠标…).在Linux中,O.S.生成器是/dev/random.或者说,有点挑剔,是/ dev / urandom(这是Python的os.urandom实际上在内部使用的).区别在于/ dev / random使用硬件中断来生成随机序列(如前所述).如果没有中断,则/ dev / random可能会用尽,您可能需要稍等片刻,直到获得下一个随机数. / dev / urandom在内部使用/ dev / random,但可以保证始终为您准备好随机数.

如果您使用的是Linux,只需在终端上执行cat / dev / random(并准备按Ctrl C,因为它将开始真正非常随机地输出内容)

borrajax@borrajax:/tmp$cat /dev/random
_+�_�?zta����K�����q�ߤk��/���qSlV��{�Gzk`���#p$�*C�F"�B9��o~,�QH���ɭ�f�޺�̬po�2o

标签:random-seed,python,random,cryptography
来源: https://codeday.me/bug/20191010/1888581.html