为什么大多数编程语言,尤其是编译型的,在生成随机数前都要设一个种子?

2016-08-16 20:41:23 +08:00
 fyyz
我理解随机数的基本原理,就是一个函数,例如 y=x+1 ,当我给出种子 x=1 的时候就生成结果 y=2 ,只不过生成随机数的函数更加复杂,其结果图像更是随机分布的点,而绝对不会像刚刚例子里举的 y=x+1 那样能画出连续的线。

但是,令我比较奇怪的是,绝大多数编程语言,尤其是编译型的,必须在生成随机数前进行类似 init() 之类的初始化操作,同时传入一个种子,比如说时间戳之类的,然后才能生成随机数。为什么这些编程语言不会在标准库的随机数函数里内置一个诸如时间戳获取器之类的种子生成器,而一定要程序员手动初始化呢?
5742 次点击
所在节点    程序员
18 条回复
bombless
2016-08-16 20:49:07 +08:00
这跟语言有啥关系……这明明就是算法设计。

这是因为最
vitovan
2016-08-16 20:49:37 +08:00
这是个好问题,待我去搜一搜。
ehs2013
2016-08-16 20:50:55 +08:00
随机数被猜到就不好了。针对随机数生成器的攻击太多了
bombless
2016-08-16 20:52:30 +08:00
因为最保险的获取种子的方式是由操作系统收集系统的熵。但是刚启动的时候系统积累的数据不足以收集这些信息,要等系统用一段时间才行。如果你的库需要随机数,那么给它一个种子就绕过了这个难题:库设计者把刚启动时没有合适的种子的困难丢给了调用者。
Kisesy
2016-08-16 20:54:24 +08:00
shippo7
2016-08-16 20:57:41 +08:00
如果使用当前系统时间作为种子,随机数可以被预测
debiann
2016-08-16 21:02:26 +08:00
如果我需要复现随机数序列呢。把两个问题分开处理不是更灵活吗
vitovan
2016-08-16 21:02:54 +08:00
r#5 @Kisesy 五楼正解。
starsoi
2016-08-16 21:13:08 +08:00
让程序员给种子的目的就是为了使程序的行为是可以复现的。
给定一个种子,随机数生成器生成的随机数序列是固定不变的。在调试程序的时候,给一个固定的种子,保证每次程序跑的时候使用的是相同的随机数序列。因为可能有些 BUG 只有在特定的随机数时才会触发,我就能保证在调试的时候每次跑都会触发这个 BUG 。如果标准库内置了变化的种子(比如用时间戳)而无法人为固定,那你就会发现,你的程序有的时候没 BUG ,有的时候有 BUG , BUG 的复现不受你的控制,从而大大增加了调试的难度。
当然,调试完成后,用于生产环境中的程序还是得用非固定值(比如时间戳)来作为种子。
binux
2016-08-16 21:18:03 +08:00
首先,指定随机种子的函数是有必要提供的,比如测试时想要 mock 掉随机状态。
其次,你也可以不初始化啊,结果不过相当于 srand(1) 罢了。
最后, rand 一般都是独立的函数,如果要用当前时间作为参数调用 srand ,那么它应该在什么时候调用呢?程序运行时,那如果不用也要初始化吗?函数第一次运行时,检测多麻烦啊。那不如干脆什么都不做,默认固定值好了。
ecloud
2016-08-16 21:36:28 +08:00
编译型语言一样有现成的第三方库,包括随机字符串,随机整数直接拿来就用,比如 Glib ,还有早年的 Delphi
uyhyygyug1234
2016-08-16 21:51:32 +08:00
解耦
zhuangzhuang1988
2016-08-16 22:06:53 +08:00
因为解释性语言已经被初始化了啊,
如 python 代码
https://github.com/python/cpython/blob/master/Modules/main.c#L378
wodesuck
2016-08-16 22:07:22 +08:00
设置同一个种子可以产生相同的随机数
比如游戏中,多个玩家可以输入相同的种子来获得完全相同的随机地图
weyou
2016-08-16 22:42:00 +08:00
因为他们都是伪随机数
wizardoz
2016-08-16 22:52:27 +08:00
如果一个库生成随机数时自动在后台调用 time() 函数作为种子。那么用这个库开发出的软件,只要提供一个虚假的 time() 函数调用接口给他,每次都给他一个固定的 时间值(或者每次运行软件之前修改系统时间到一个特定的值),那么这个软件就每次随机数都得到同一个结果。你觉得这样的库有人敢用吗?
fuyufjh
2016-08-17 13:17:27 +08:00
@weyou 正解
lizon
2016-08-17 13:35:53 +08:00
把生成的随机序列可否被预测,这个选项留给使用者,因为有时候需要能重现生成的随机序列,比如:游戏战斗回放

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/299739

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX