为了账号安全,请及时绑定邮箱和手机立即绑定

Python 中的随机函数预测

Python 中的随机函数预测

HUH函数 2023-12-12 15:41:16
根据Random库的文档,假设开发人员没有提供任何种子(None),该函数使用系统当前时间作为种子(time.time())。不幸的是,输出似乎没有反映文档print(random.randrange(1,10)) a=time.time() . . . . random.seed(a)print(random.randrange(1,10))上面的代码产生 2 个不同的输出,因此假设我使用 Windows 10(对于那些可能会考虑 urandom 供应商方向的人)和 Python 3,我的问题是:1.为什么上面的代码没有产生相同的输出2.如何让它产生相同的输出3.当我试图在 Random.py 中找到种子分配部分时,我找不到任何 time.time() 分配给 Random.seed 的地方,所以如果有人可以参考该部分,我将不胜感激
查看完整描述

1 回答

?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

这实际上是一个有趣的问题。


首先,您可能会通过连续调用获得相同的结果time.time(),但主要是由于精度。


In [36]: a=time.time(); b=time.time()


In [37]: b-a

Out[37]: 0.0

现在让我们进入问题:


由于初始种子的生成方式不同,它不会产生相同的输出。如果您查看random.py源代码,seed()您会看到它指定

def seed(self, a=None, version=2):

   """Initialize internal state from a seed.

   The only supported seed types are None, int, float,

   str, bytes, and bytearray.

   None or no argument seeds from current time or from an operating

   system specific randomness source if available.

因为没有参考,所以time.time()你不能假设它使用它。事实上,您可以查看CPython实现的源代码(如果您了解 C)。如果需要的话,它有助于保证随机种子的方法之一是:


static void

random_seed_time_pid(RandomObject *self)

{

    _PyTime_t now;

    uint32_t key[5];


    now = _PyTime_GetSystemClock();

    key[0] = (uint32_t)(now & 0xffffffffU);

    key[1] = (uint32_t)(now >> 32);


    key[2] = (uint32_t)getpid();


    now = _PyTime_GetMonotonicClock();

    key[3] = (uint32_t)(now & 0xffffffffU);

    key[4] = (uint32_t)(now >> 32);


    init_by_array(self, key, Py_ARRAY_LENGTH(key));

}

对不同时钟和进程 ID 进行多次调用。没有关于time.time(). 由于种子是如何生成的,两个连续的种子几乎不可能相同。


如果您希望某些东西产生相同的输出,则需要以相同的方式播种。

In [42]: import random


In [43]: a = time.time()


In [44]: random.seed(a)


In [45]: random.randrange(100)

Out[45]: 98


In [46]: random.randrange(100)

Out[46]: 94


In [47]: random.seed(a)  # Reset


In [48]: random.randrange(100)

Out[48]: 98

不过,它不一定是数字。您可以使用许多不同的选项来播种。


希望上面提供的源代码可以解决这个问题。


查看完整回答
反对 回复 2023-12-12
  • 1 回答
  • 0 关注
  • 105 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信