This topic created in 3562 days ago, the information mentioned may be changed or developed.
我理解随机数的基本原理,就是一个函数,例如 y=x+1 ,当我给出种子 x=1 的时候就生成结果 y=2 ,只不过生成随机数的函数更加复杂,其结果图像更是随机分布的点,而绝对不会像刚刚例子里举的 y=x+1 那样能画出连续的线。
但是,令我比较奇怪的是,绝大多数编程语言,尤其是编译型的,必须在生成随机数前进行类似 init() 之类的初始化操作,同时传入一个种子,比如说时间戳之类的,然后才能生成随机数。为什么这些编程语言不会在标准库的随机数函数里内置一个诸如时间戳获取器之类的种子生成器,而一定要程序员手动初始化呢?
18 replies • 2016-08-17 13:35:53 +08:00
 |
|
1
bombless Aug 16, 2016 via Android
这跟语言有啥关系……这明明就是算法设计。
这是因为最
|
 |
|
2
vitovan Aug 16, 2016
这是个好问题,待我去搜一搜。
|
 |
|
3
ehs2013 Aug 16, 2016
随机数被猜到就不好了。针对随机数生成器的攻击太多了
|
 |
|
4
bombless Aug 16, 2016 via Android 1
因为最保险的获取种子的方式是由操作系统收集系统的熵。但是刚启动的时候系统积累的数据不足以收集这些信息,要等系统用一段时间才行。如果你的库需要随机数,那么给它一个种子就绕过了这个难题:库设计者把刚启动时没有合适的种子的困难丢给了调用者。
|
 |
|
6
shippo7 Aug 16, 2016 via iPhone
如果使用当前系统时间作为种子,随机数可以被预测
|
 |
|
7
debiann Aug 16, 2016 via iPhone
如果我需要复现随机数序列呢。把两个问题分开处理不是更灵活吗
|
 |
|
9
starsoi Aug 16, 2016
让程序员给种子的目的就是为了使程序的行为是可以复现的。 给定一个种子,随机数生成器生成的随机数序列是固定不变的。在调试程序的时候,给一个固定的种子,保证每次程序跑的时候使用的是相同的随机数序列。因为可能有些 BUG 只有在特定的随机数时才会触发,我就能保证在调试的时候每次跑都会触发这个 BUG 。如果标准库内置了变化的种子(比如用时间戳)而无法人为固定,那你就会发现,你的程序有的时候没 BUG ,有的时候有 BUG , BUG 的复现不受你的控制,从而大大增加了调试的难度。 当然,调试完成后,用于生产环境中的程序还是得用非固定值(比如时间戳)来作为种子。
|
 |
|
10
binux Aug 16, 2016 1
首先,指定随机种子的函数是有必要提供的,比如测试时想要 mock 掉随机状态。 其次,你也可以不初始化啊,结果不过相当于 srand(1) 罢了。 最后, rand 一般都是独立的函数,如果要用当前时间作为参数调用 srand ,那么它应该在什么时候调用呢?程序运行时,那如果不用也要初始化吗?函数第一次运行时,检测多麻烦啊。那不如干脆什么都不做,默认固定值好了。
|
 |
|
11
ecloud Aug 16, 2016
编译型语言一样有现成的第三方库,包括随机字符串,随机整数直接拿来就用,比如 Glib ,还有早年的 Delphi
|
 |
|
14
wodesuck Aug 16, 2016
设置同一个种子可以产生相同的随机数 比如游戏中,多个玩家可以输入相同的种子来获得完全相同的随机地图
|
 |
|
15
weyou Aug 16, 2016
因为他们都是伪随机数
|
 |
|
16
wizardoz Aug 16, 2016
如果一个库生成随机数时自动在后台调用 time() 函数作为种子。那么用这个库开发出的软件,只要提供一个虚假的 time() 函数调用接口给他,每次都给他一个固定的 时间值(或者每次运行软件之前修改系统时间到一个特定的值),那么这个软件就每次随机数都得到同一个结果。你觉得这样的库有人敢用吗?
|
 |
|
18
x8 Aug 17, 2016
把生成的随机序列可否被预测,这个选项留给使用者,因为有时候需要能重现生成的随机序列,比如:游戏战斗回放
|