我知道我可以通过使用种子调用来“重新启动”我rand
的调用srand
,但这肯定会影响未来对rand
其他库方法的调用,包括加密方法?
如何在某些地方重复我的随机性并仍然确保我的其余代码不受影响?
(Ruby 1.9.2)您可以序列化一个随机生成器,将其存储在一个文件中,并将该文件与您的程序一起提供。
创建文件:
File.open('random_generator.marshal', 'w'){ |f| Marshal.dump(Random.new, f) }
在程序中使用随机生成器:
f = File.open( 'random_generator.marshal', 'r' )
r = Marshal.load( f )
f.close
10.times{ puts r.rand } #repeatable
使用简单随机gem。
(在 ruby 1.9.3 中)有一个更简单的解决方案使用Random
.
您需要使用r = Random.new(seed)
来获取可用于生成随机调用的对象r.rand
。这是可重复的,只会影响对r.rand
not的调用Kernel.rand
。
兰德():
...Kernel::srand 可用于确保程序不同运行之间随机数的可重复序列...。
srand():
将伪随机数生成器播种到 number.to_i.abs 的值。...通过将种子设置为已知值,可以在测试期间使脚本具有确定性...。
您可以存储您的种子值和用户进行的迭代次数,然后在稍后使用该值重新设置种子,然后循环他们之前使用它的次数以跳过以前的值,然后登陆您在序列中的下一个值。这是我所知道的尝试恢复序列的唯一方法。如果您担心其他例程/线程,请在设置 srand 之前获取原始种子并将其存储,获取下一个数字,然后恢复原始种子。
如果您担心影响依赖它的其他例程的随机性,我认为这些例程的作者应该做一些事情来确保他们处理的是真正的随机种子。你真的只能关心你的代码而不是杀死系统。除此之外,责任就变成了他们的。
如果您使用的是 JRuby,则只需实例化一个java.util.Random
.