【发布时间】:2019-08-20 12:09:36
【问题描述】:
我正在寻找一种方法来生成一个好的种子,以便在同时开始的进程中生成不同系列的随机数。 我想避免使用数学或加密库之一,因为我非常频繁地选择随机数并且我的 cpu 资源非常有限。
我找到了几个设置种子的例子。我使用以下方法对其进行了测试:
- 从 5000 个选项中选择 100 个随机数的短程序。所以每个值都有 2% 的机会被选中。
- 运行这个程序 100 次,所以理论上,在一个真正随机的环境中,所有可能的值都应该至少选择一次。
- 计算根本未选择的值的数量。
这是我使用的 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);
}
我运行程序 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
表格显示了测试的结果(值越小越好):
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`
恒定种子方法显示未选择 986 或 1000 个值。换言之,仅选择了 1.4% 的可能值。这足以接近预期的 2%。
但是,我预计在少数地方推荐的最后一个选项会明显优于默认选项。
有没有更好的方法为每个进程生成种子?
【问题讨论】:
-
您的应用程序中是否需要可重复的“随机性”?您将生成的随机数将如何使用?
-
没有。为了获得可重复的“随机性”,我可以简单地使用相同的种子。
-
您能否回答我的另一个问题:您生成的随机数将如何使用?如果这些数字会以任何方式提高信息安全性(例如,它们用作随机密码、随机数或加密密钥),那么您应该简单地使用加密 RNG(例如 Perl 中的
Crypt::URandom)并生成 随机数字 用它而不是 seeds。 -
使用随机数我将组成一个“用户名”:
$user_name_to_fetch = sprintf("name%015d", rand($max_user_id));从数据库中查询。我想通过在多个客户端进程中运行查询,在最短的时间内覆盖大多数数据库。如何使用Crypt::URandom生成随机数?它生成随机字符串。 -
地穴::随机::种子。试一试,并使用 TESHA2-strong 方法对其性能进行基准测试/分析。如果您只在需要种子时调用它,它可能会非常快。播种 RNG 后,在可预见的未来您不必再次播种。
标签: perl random random-seed