为什么大多数编程语言,尤其是编译型的,在生成随机数前都要设一个种子? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
fyyz
V2EX    程序员

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

  •  1
     
  •   fyyz 2016-08-16 20:41:23 +08:00 6371 次点击
    这是一个创建于 3404 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我理解随机数的基本原理,就是一个函数,例如 y=x+1 ,当我给出种子 x=1 的时候就生成结果 y=2 ,只不过生成随机数的函数更加复杂,其结果图像更是随机分布的点,而绝对不会像刚刚例子里举的 y=x+1 那样能画出连续的线。

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

    这是因为最
    vitovan
        2
    vitovan  
       2016-08-16 20:49:37 +08:00
    这是个好问题,待我去搜一搜。
    ehs2013
        3
    ehs2013  
       2016-08-16 20:50:55 +08:00
    随机数被猜到就不好了。针对随机数生成器的攻击太多了
    bombless
        4
    bombless  
       2016-08-16 20:52:30 +08:00 via Android   1
    因为最保险的获取种子的方式是由操作系统收集系统的熵。但是刚启动的时候系统积累的数据不足以收集这些信息,要等系统用一段时间才行。如果你的库需要随机数,那么给它一个种子就绕过了这个难题:库设计者把刚启动时没有合适的种子的困难丢给了调用者。
    Kisesy
        5
    Kisesy  
       2016-08-16 20:54:24 +08:00   3
    shippo7
        6
    shippo7  
       2016-08-16 20:57:41 +08:00 via iPhone
    如果使用当前系统时间作为种子,随机数可以被预测
        7
    debiann  
       2016-08-16 21:02:26 +08:00 via iPhone
    如果我需要复现随机数序列呢。把两个问题分开处理不是更灵活吗
    vitovan
        8
    vitovan  
       2016-08-16 21:02:54 +08:00
    r#5 @Kisesy 五楼正解。
    starsoi
        9
    starsoi  
       2016-08-16 21:13:08 +08:00
    让程序员给种子的目的就是为了使程序的行为是可以复现的。
    给定一个种子,随机数生成器生成的随机数序列是固定不变的。在调试程序的时候,给一个固定的种子,保证每次程序跑的时候使用的是相同的随机数序列。因为可能有些 BUG 只有在特定的随机数时才会触发,我就能保证在调试的时候每次跑都会触发这个 BUG 。如果标准库内置了变化的种子(比如用时间戳)而无法人为固定,那你就会发现,你的程序有的时候没 BUG ,有的时候有 BUG , BUG 的复现不受你的控制,从而大大增加了调试的难度。
    当然,调试完成后,用于生产环境中的程序还是得用非固定值(比如时间戳)来作为种子。
    binux
        10
    binux  
       2016-08-16 21:18:03 +08:00   1
    首先,指定随机种子的函数是有必要提供的,比如测试时想要 mock 掉随机状态。
    其次,你也可以不初始化啊,结果不过相当于 srand(1) 罢了。
    最后, rand 一般都是独立的函数,如果要用当前时间作为参数调用 srand ,那么它应该在什么时候调用呢?程序运行时,那如果不用也要初始化吗?函数第一次运行时,检测多麻烦啊。那不如干脆什么都不做,默认固定值好了。
    ecloud
        11
    ecloud  
       2016-08-16 21:36:28 +08:00
    编译型语言一样有现成的第三方库,包括随机字符串,随机整数直接拿来就用,比如 Glib ,还有早年的 Delphi
    uyhyygyug1234
        12
    uyhyygyug1234  
       2016-08-16 21:51:32 +08:00 via Android
    解耦
    zhuangzhuang1988
        13
    zhuangzhuang1988  
       2016-08-16 22:06:53 +08:00
    因为解释性语言已经被初始化了啊,
    如 python 代码
    https://github.com/python/cpython/blob/master/Modules/main.c#L378
    wodesuck
        14
    wodesuck  
       2016-08-16 22:07:22 +08:00
    设置同一个种子可以产生相同的随机数
    比如游戏中,多个玩家可以输入相同的种子来获得完全相同的随机地图
    weyou
        15
    weyou  
       2016-08-16 22:42:00 +08:00
    因为他们都是伪随机数
    wizardoz
        16
    wizardoz  
       2016-08-16 22:52:27 +08:00
    如果一个库生成随机数时自动在后台调用 time() 函数作为种子。那么用这个库开发出的软件,只要提供一个虚假的 time() 函数调用接口给他,每次都给他一个固定的 时间值(或者每次运行软件之前修改系统时间到一个特定的值),那么这个软件就每次随机数都得到同一个结果。你觉得这样的库有人敢用吗?
    fuyufjh
        17
    fuyufjh  
       2016-08-17 13:17:27 +08:00
    @weyou 正解
    x8
        18
    x8  
       2016-08-17 13:35:53 +08:00
    把生成的随机序列可否被预测,这个选项留给使用者,因为有时候需要能重现生成的随机序列,比如:游戏战斗回放
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5792 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 02:08 PVG 10:08 LAX 18:08 JFK 21:08
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86