gpt4 book ai didi

python - 使用来自 python 的硬件 rng

转载 作者:太空狗 更新时间:2023-10-30 00:55:57 28 4
gpt4 key购买 nike

是否有任何现成的库,以便 numpy 程序可以使用 intel 硬件 prng (rdrand) 来填充随机数缓冲区?

如果做不到这一点,有人可以为我指明正确的方向,让我可以改编或使用一些 C 代码(我将 CPython 和 Cython 与 numpy 一起使用,因此最低限度的包装器就足够了)。

我要的随机数生成器是[0,1]之间的均匀随机数。

最佳答案

此代码将使用/dev/urandom (Unix) 或 CryptGenRandom API (Windows)。使用哪种 RNG,硬件还是软件,取决于操作系统。

如果要精确控制使用哪个生成器,则必须通过其硬件驱动程序或库进行查询。当您将随机位作为字符串时,您可以使用 np.fromstring 以类似于此代码的方式进行。

通常我们可以相信操作系统会为其加密服务使用最好的熵源,包括随机位生成器。如果有硬件 RNG,它很可能会被使用,通常与其他熵源结合使用。

import os
import numpy as np

def cryptorand(n):
a = np.fromstring(os.urandom(n*4), dtype=np.uint32) >> 5
b = np.fromstring(os.urandom(n*4), dtype=np.uint32) >> 6
return (a * 67108864.0 + b) / 9007199254740992.0

这是在 Mac OS X 上使用此方法生成的 1,000,000 个随机偏差的分布。如您所见,它在 [0,1] 上非常均匀:

enter image description here

如果您需要真正强大的密码随机偏差,您可以使用/dev/random 而不是/dev/urandom。这仅适用于类 Unix 系统,不适用于 Windows:

import numpy as np

def cryptorand(n):
with open('/dev/random','rb') as rnd:
a = np.fromstring(rnd.read(n*4), dtype=np.uint32) >> 5
b = np.fromstring(rnd.read(n*4), dtype=np.uint32) >> 6
return (a * 67108864.0 + b) / 9007199254740992.0

请注意,与使用 os.urandom 作为熵源的版本不同,此函数可能会阻塞。

(编辑 1:更新规范化以等同于 NumPy 的规范化)

编辑 2:评论表明问题的原因是速度,而不是密码强度。硬件RNG的目的不是速度而是强度,所以做题无效。然而,可以替代 Mersenne Twister 的快速且良好的 PRNG 是 George Marsaglia 的 multiply-with-carry 生成器。这是 Cython 中的一个简单实现:

import numpy as np
cimport numpy as cnp

cdef cnp.uint32_t gw = 152315241 # any number except 0 or 0x464fffff
cdef cnp.uint32_t gz = 273283728 # any number except 0 or 0x9068ffff

def rand(cnp.intp_t n):
"""Generate n random numbers using George Marsaglia's
multiply-with-carry method."""
global gw, gz
cdef cnp.uint32_t w, z, a, b
cdef cnp.intp_t i
cdef cnp.ndarray x = cnp.PyArray_SimpleNew(1, &n, cnp.NPY_FLOAT64)
cdef cnp.float64_t *r = <cnp.float64_t*> cnp.PyArray_DATA(x)
w,z = gw,gz
for i in range(n):
z = 36969 * (z & 65535) + (z >> 16)
w = 18000 * (w & 65535) + (w >> 16)
a = (z << 16) + w
z = 36969 * (z & 65535) + (z >> 16)
w = 18000 * (w & 65535) + (w >> 16)
b = (z << 16) + w
r[i] = (a * 67108864.0 + b) / 9007199254740992.0
gw,gz = w,z
return x

请注意,Mersenne Twister 和进位乘法都没有加密强度。

关于python - 使用来自 python 的硬件 rng,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22680441/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com