ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-10-11 00:00:35  阅读:265  来源: 互联网

标签:random-seed python random cryptography


说我有一些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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有