提问人:betacrash 提问时间:7/11/2023 最后编辑:betacrash 更新时间:7/11/2023 访问量:181
如何从 /dev/urandom 获取随机种子?
How to get a random seed from /dev/urandom?
问:
在 python 3.11 和 ubuntu 22.04 中,我试图获取一个随机种子(而不是来自种子系统的随机数)。我有一个系统正在运行一个循环的进程。在循环的不同点,我将所有 python 和系统 RNG 设置设置为特定的种子以提高可重复性。在某个特定点上,我需要一个随机种子,与用于系统的特定种子分开。
我需要的随机种子是一个上限为 (2^32 -1) 的整数。是的,有一个函数,但它从种子系统返回一个值。
我在 USB 端口中有一个硬件 RNG,可以与 rng5-tools 包一起使用,但我无法直接访问它。我假设它用于填充熵池,并且 os.urandom() 从该池中提取位。
我尝试使用 os.urandom() 生成一个整数,然后取该整数的最后一个字符。10 个字符(0 到 9)的分布是均匀的。我已经运行了 10^3 到 10^7 的样本来验证这一点。
我这样做了 10 次,每次将单个字符添加到字符串中,然后将字符串转换为整数。每次我向字符串添加整数时,我都会用零填充它并测试它是否< 4294967296 (2^32 -1)。如果失败,则丢弃该角色,并获取并测试一个新角色,直到它通过测试。如果成功,我会将其保留在字符串中,并对新字符重复该过程,直到总共获得十个字符。然后,我将字符串转换为整数。
但是,生成的整数的分布是偏态的,如图所示。谁能解释一下为什么?代码为:
def gen_seed(digits = 10):
ssc = ""
for i in range(digits):
found_digit = False
while found_digit == False:
rand=f"{int.from_bytes(os.urandom(1), sys.byteorder)}"
digit = f"{rand[-1]}"
ssc_test = int(f"{ssc}{digit}".ljust(10,"0"))
if ssc_test < 4294967296:
found_digit = True
ssc = f"{ssc}{digit}"
ss = int(ssc)
return(ss)
答:
3赞
Barmar
7/11/2023
#1
从中获取所需的字节数,然后将其转换为整数。os.urandom()
def gen_seed(num_bytes = 4):
b = os.urandom(num_bytes)
return int.from_bytes(b)
评论
0赞
betacrash
7/12/2023
嗨,Barmar,这似乎在 2^32 -1 范围内产生了一个统一的差异。我想知道你或任何人是否可以告诉我有关os.urandom(bytes)的信息。它是否在不替换的情况下从熵池中提取 8 x 字节数的位数?还是只使用池中 8 x 字节熵位的一小部分?
0赞
Sam Mason
7/12/2023
@betacrash提到 Linux,它可能值得一读:zx2c4.com/projects/linux-rng-5.17-5.18 它描述了代码的最新重构,并包括一些历史和动机
0赞
betacrash
7/12/2023
@Barmar:你回答了如何获得统一号码。我们可以用这个来结束这个问题。但这引出了另一个问题,我将为此发表另一篇文章。
0赞
betacrash
7/12/2023
@Sam:谢谢你的参考。这增加了我将在另一篇文章中提出的下一个问题。
评论
4
1e9 / (2**32 % 1e9)