博舍

真随机和伪随机区别 计算机生成的随机数是伪随机吗为什么

真随机和伪随机区别

​很久以前流传着这样一则笑话:一个身患重病的人决定去动手术。在手术之前,他问医生:“这起手术的成功率是多少?”医生回答他:“只有1%。”他很惊慌,但是医生说:“没事的,在你之前我已经治死过99个人了。”

这是一则嘲笑那些不懂“概率”的人的笑话,却讲出了“真随机”和“伪随机”之间的区别。

在四月末的时候,我曾写过一篇《你打游戏靠的是技术,还是运气?》,其中就提及了“伪随机”这个概念。当时受限于篇幅,没有详细展开解释“伪随机”的概念。前不久,在因国际邀请赛而备受关注的Dota2在最近一次的更新中,有这么一条更新内容:“落空的负面效果和下坡攻击的落空效果现在都采用伪随机触发”。

那么到底什么是“伪随机”呢?以及和“伪随机”对应的“真随机”又是什么概念?

在讨论真随机和伪随机之前,先排除另一个容易搞混的错误答案:赝随机数。

赝随机数算法(Pseudo-RandomNumberGenerator,简称PRNG)是计算机的一个术语——当然,它也可以被叫做“伪随机数算法”,只是为了方便与游戏中的“伪随机数”进行区分,本文中统一称作“赝随机数算法”。

众所周知,计算机程序是由无数“0”和“1”两种状态构成的,如果一个状态不是“0”,那就必定是“1”,颇有种非黑即白的味道。

为什么计算机永远不可能产生真正的随机数

如果你需要随机选择,你可以抛硬币或掷骰子。如果你这样做了,你就占了电脑的上风。因为计算机软件永远不能生成真正的随机数。当你想在shuffle上播放你最喜欢的专辑时,这并不是那么重要,但当涉及到高风险领域,如安全和赌博时,这就变得不太一样了。

现代电脑可以做一些非常惊人的事情。那么,为什么他们不能做一些像模拟掷骰子这样简单的事情呢?这一切都归结于电脑编程的方式。计算机遵循算法,这些算法本质上就是如何执行任务的指令列表。他们是指令的执行者,所以完全可以预测。尽管如此,工程师们还是很聪明的,他们想出了一些不同的方法来让计算机生成非常接近随机数字的东西,因为它们不能生成真正的随机数字。

产生看似随机数的一种方法是使用伪随机数生成器。这些算法使用数学公式或预先确定的数字表来创建随机的数字序列。如今,生成伪随机数的算法是如此之好,以至于需要一些真正的侦查工作才能确定这些数字实际上不是随机的。不过,这是可能的。有了正确的编程能力,你就可以对用于运行在线扑克游戏的伪随机数进行反向工程,或者对敏感数据进行加密,就可以得到很多其他人的钱。

你可以认为真随机数生成器,第二种方法,确实产生随机性。但是我们需要你在技术上的帮助。原因如下:真随机数生成器使用物理现象来提取实际的随机性,然后使用这些随机现象来生成随机数。这些物理现象可能像掷骰子一样简单,但它们通常更容易测量,比如放射性衰变、大气中的背景噪音,甚至是一个人敲击键盘的间隔时间。在真随机数生成器中仍然存在一些算法,而算法从来都不是真正随机的。

电脑随机数是如何生成的

转自:http://www.chncla.com/yk/201006/p_7.html

 

最近浏览“程序员论坛”时发现不少好帖,增长了不少知识,现拿其中一则为例与大家共同分享心得。

某人提出一个问题:怎样才能生成一亿个不重复的随机数?

问题表述起来很简单,似乎只要弄明白什么叫随机数以及怎样用电脑生成随机数,就能解决问题。

随机数,个人理解为一定范围内出现的毫无规律的数,比如扔一个骰子,落在桌面上时朝上的一面所表示的数就是随机数,这个数只能在1到6的范围内,但具体是什么数,谁也不能肯定,因为它没有规律。一组不重复的随机数,对扔骰子来说就是扔出六个不一样的数来,再比如洗一次扑克牌,洗完后就是54张不重复的随机数。

第二个问题,怎么样用电脑生成随机数?只要调用某个语言的某个函数即可。其实电脑是没办法生成真正的随机数,因为电脑是高度有规律的机器,让它生成一个没规律的数,根本办不到。平时程序员用某个函数生成的随机数,只是利用某个算法弄出来的伪随机数,看起来像,其实不是,能解决问题就行。

回到这个帖子所描述的问题上来。生成一亿个不重复的随机数,最直接的算法就是每用函数生成一个数,就把它放在一个筐里,第一个数直接放到筐里,以后生成的数在放到筐里之前和筐里的每一个数比较一番,一旦发现筐里有和新生成的数一样的数时,丢掉这个新生成的数,再接着生成数。

毫无疑问,这种算法的效率非常低,看看其中的比较次数就知道了,最差的次数趋于无穷次。也就是说到后来,几乎生成不了和以往不同的数。

当然还可以将这个算法升级为效率高得多的算法,每生成一个数,把这个数从随机数生成器取的范围中去掉,比如要生成10个随机数,第一次生成一个3,我把3从随机数的范围中去掉,第二次只从1到9这个范围内找。3对应4,4对应5……9对应10。这样就不存在比较的环节,然而又多出一个对应的环节,每生成一个数之后就要把剩下的数重新对应一遍,效率也不容乐观。

目前以我为代表的普通程序员的想象力也就到此为止,想不出什么高级解决办法,就当扔一块砖头出来,下面就把真正的碧玉——数学家级程序员的算法隆重介绍请出来。

我们先用另一种眼光来看不重复的随机数:加密。把一个能看懂的英文字符串打乱字母的顺序,变成不可读,这就是加密。但必须得有规律地打乱,字母a对应另外一个固定的字母Ax,字母b对应另外一个固定的字母Bx,以此类推,而且必须一一对应的。那么字符串“ab…z”这26个字母对应的26个加密字母“AxBx和Zx”就可以看成是对应范围a到z的不重复的伪随机数,这就是数学家的算法的来源。

看看回帖者的原文:

“可以采用32bitRSA算法设A从2~(N-1)C=(AEXPD)modN满足如下条件:D是素数,N是两个素数(P,Q)之积,(D*E)mod((P-1)*(Q-1))=1因为:若C=(AEXPD)modN有:A=(CEXPE)modN所以,C与A一一对应。所以,对于A=2~(N-1),有不重复,无遗漏的伪随机码C。”

 

凡是稍微扯上一点数学,尤其是高等数学的问题,我等泛泛之辈看起来就有点费劲,这里虽然文字不长,但是还得慢慢来看。

这里面RSA算法是密码学三大算法之一(RSA、MD5、DES),是一种不对称密码算法。说如果满足条件:D是素数,N是两个素数(P,Q)之积,(D*E)mod((P-1)*(Q-1))=1,那么存在C与A(范围从2到N-1)一一对应,且C=(AEXPD)modN。A是一个有顺序的数,C就是一个看似无规律的伪随机数。Mod运算表示求模,例如7Mod3=1。意思是7除以3余1。类似地8Mod3=2,9Mod3=0。EXP表示前面数的后面数次方,AEXPD表示A的D次方。这两个运算清楚了,其它的也就没什么困难的了,*是乘法的意思,大多数理科生都清楚。

搜了一下网络,还得加上一些条件,1,P和Q不能一样。2,e

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

上一篇

下一篇