如何产生好的种子

Yuv*_*val 1 random perl random-seed

我正在寻找一种方法来生成良好的种子,以便在同时开始的过程中生成不同系列的随机数。我想避免使用数学库或加密库之一,因为我经常选择随机数,而且我的CPU资源非常有限。

我发现很少有树立种子的例子。我使用以下方法测试了它们:

  1. 简短的程序,可从5000个选项中选择100个随机数。因此,每个值都有2%的机会被选择。
  2. 运行此程序100次,因此从理论上讲,在真正随机的环境中,应至少选择一次所有可能的值。
  3. 计算根本没有选择的值的数量。

这是我使用的perl代码。在每个测试中,我仅选择一种生成种子的方法:

#!/usr/bin/perl
#$seed=5432;
#$seed=(time ^ $$);
#$seed=($$ ^ unpack "%L*", `ps axww | gzip -f`);
$seed=(time ^ $$ ^ unpack "%L*", `ps axww | gzip -f`);

srand ($seed);

for ($i=0 ; $i< 100; $i++) {
        printf ("%03d \n", rand (5000)+1000);
}

Run Code Online (Sandbox Code Playgroud)

我将程序运行了100次,并使用以下方法计算了未选择的值:

# run the program 100 times
for i in `seq 0 99`; do /tmp/rand_test.pl ; done  > /tmp/list.txt
# test 1000 values (out of 5000). It should be good-enough representation.
for i in `seq 1000 1999`; do echo -n "$i  "; grep -c $i /tmp/list.txt; done   | grep " 0" | wc -l

Run Code Online (Sandbox Code Playgroud)

下表显示了测试结果(值越低越好):

count      Seed generation method
114    default - the line: "srand ($seed);" is commented ou
986    constant seed (5432)
122    time ^ $$
125    $$ ^ unpack "%L*", `ps axww | gzip -f`
163    time ^ $$ ^ unpack "%L*", `ps axww | gzip -f`
Run Code Online (Sandbox Code Playgroud)

恒定种子方法显示未选择986或1000个值。换句话说,仅选择了1.4%的可能值。这已经足够接近预期的2%。

但是,我希望在少数几个地方推荐的最后一个选项将明显优于默认选项。

是否有更好的方法为每个过程生成种子?

dax*_*xim 5

我经常选择随机数,而我的CPU资源非常有限。

您甚至在进行测量之前就担心。

是否有更好的方法为每个过程生成种子?

是。您必须留出易于操纵的用户空间。只需使用Crypt :: URandom即可

  • 它对于任何目的都是安全的,包括获取种子。
  • 它将对每个操作系统使用内核CSPRNG(请参阅源代码),因此可以避免上面文章中显示的问题。
  • 它没有遭受记录的rand弱点的困扰。