Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/360.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:random.random()种子在哪里?_Python_Random_Cryptography_Random Seed - Fatal编程技术网

Python:random.random()种子在哪里?

Python:random.random()种子在哪里?,python,random,cryptography,random-seed,Python,Random,Cryptography,Random Seed,假设我有一些python代码: import random r=random.random() 一般来说,r的值是从哪里来的? 如果我的操作系统没有随机,那么它的种子在哪里呢? 为什么不建议将其用于加密?有没有办法知道随机数是什么?遵循da代码 要查看random模块在系统中的位置,您只需在终端中执行以下操作: >>> import random >>> random.__file__ '/usr/lib/python2.7/random.pyc' 这为您

假设我有一些python代码:

import random
r=random.random()
一般来说,r的值是从哪里来的?
如果我的操作系统没有随机,那么它的种子在哪里呢?
为什么不建议将其用于加密?有没有办法知道随机数是什么?

遵循da代码

要查看
random
模块在系统中的位置,您只需在终端中执行以下操作:

>>> import random
>>> random.__file__
'/usr/lib/python2.7/random.pyc'
这为您提供了
.pyc
(“已编译”)文件的路径,该文件通常与原始
.py
并排放置,在那里可以找到可读的代码

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

您将看到,它创建了
Random
类的一个实例,然后(在文件底部)将该实例的方法“升级”为模块函数。巧妙的把戏。当
random
模块被导入到任何地方时,就会创建该
random
类的一个新实例,然后初始化它的值,并将这些方法重新分配为模块的函数,使得它在每次导入(erm…或每个python解释器实例)的基础上都是随机的

这个
Random
类在其
\uuuuu init\uuuuu
方法中所做的唯一一件事就是对其进行种子设定:

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
评论已经告诉我们发生了什么。。。此方法尝试使用操作系统提供的默认随机生成器,如果没有,则将使用当前时间作为种子值

但是,等等。。。那是什么鬼东西

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

from os import urandom as _urandom
from binascii import hexlify as _hexlify
塔达阿。。。种子是一个16字节的数字,来自

假设我们在一个文明的操作系统中,比如Linux(带有一个真正的随机数生成器)。
随机
模块使用的种子与执行以下操作相同:

>>> 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
。。。另一方面,哪种类型会破坏目的(请参阅关于伪随机数生成的内容),这实际上是一种可取的特性

这就是为什么依赖操作系统随机数生成器被认为“更好”的原因。这些通常是基于硬件中断来计算的,在Linux中,O.S.generator是非常非常随机的(包括硬盘读取、用户键入的按键、移动鼠标……)。或者,有点挑剔,
/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�你有一个类似的问题。拥有真正的随机性并不总是更好的。OP确实询问了加密技术,但即使这样,你也应该知道你使用数据的目的(例如,Salsa总是从0生成0)。植入伪随机数生成器对于可复制但任意的数据非常有用,特别是对于可重复测试或在随机生成的游戏中共享级别。@YannVernier,correct,correct。这就是为什么我添加了一个澄清注释,指出有时使用相同的种子作为一个功能是可取的。非常详细的答案。
>>> import random
>>> random.seed(1)
>>> random.randint(0,100)
13
>>> random.randint(0,100)
85
>>> random.randint(0,100)
77