为什么有程序员都说取的随机数是伪随机数?

我用的是c++我就以c++为例,在编程中使用随机数的时候必定要包含特定的函数,比如利用时间产生“随机数”就必须要包含time.h头文件,这就导致了所产生的随机数其实和时间是有一定的关系的,通过读取系统的时间,将时间带入到特定的公式当中,然后产生随机数是有一定规律存在的,所以称之为伪随机数当然不止能通过时间来获取随机数,还能通过敲击键盘的时间间隔,特定的中断等产生随机数,这些随机数一样都是存在一定的规律。


伪随机是指在有限次数内随机,出现相同的数字。要实现真随机,小编认为主要把握两点:

1.种子。种子要选取带有唯一性的值,如时间。这样就从源头避免了伪随机。

2.算法。只要在有限次数内不重复,就达到了真随机。因此,算法实现一组随机数,每个都不同(相同的已拿掉,算法的好坏决定了出现相同数字的概率),这样应用时再从这组数中取出,就保证了不重复。

随机数在应用开发中,尤其是游戏开发中常用,这是个常见的问题,需从种子和算法上着手解决。

谢谢大家。


因为你每个随机数其实都是通过计算得出来的。也就是说可通过公式计算的。那他就不是真正的随机数。你设置了随机数种子,只是为这条公式设置一个变量x。让公式更复杂,但是他还是可计算的。随机是不可预知计算的。如果要得到真正的随机数。那就需要给它提供一个随机参数。骰子的点数当做随机数种子之类的


怎样才叫真随机?从1-100随机取,取100次,正好把100个数各取一次?每次的顺序还不能相同。但现实里,很可能是好多数取过好几次,而有的一次也取不到,这样才是真实一点的随机吧。


严格来说,根本不存在真随机数,不仅计算机做不到,整个世界都做不到。

我们先聊一下几种常见的随机数吧。

第一种是通常大家说的伪随机数

想起我刚学c语言的时候,经常用到的rand函数,它是个标准伪随机数生成器。每次运营程序,产生的结果都是一样的。这种伪随机数是通过一个确定的随机数发生器产生的,它仅仅能保证生成很多个数的时候,在统计上趋于均匀分布。

第二种是通常大家说的接近真随机的数

它和第一种方法类似,但是可以通过一个变化的种子使得它看起来更随机。一个常见的用法就是以时间作为种子,这样就不会出现多次执行程序出现一样结果的bug了,然而,这还是伪随机,对于确定的种子来说。它还是一个确定的过程

第三种是通常大家说的真随机数

这种通常是取自物理上的变量,比如大气污染指数小数点第5位,白噪声小数点第3位。看起来足够随机了吧。其实它还是确定事件,在确定的外因下,这些物理数据依然是确定的。并且前一秒的数据和后一秒是有关联的。

我还听到一个说法,利用量子物理的测不准理论,但其实它还是个确定事件,测不准只是人类的认知有限,从上帝视角来看,根本不存在随机的说法!


因为都是通过一个随机数生成算法生成的,依赖于种子来产生不同的随机序列。一般使用时间作为种子,但是如果种子一样的话,我们就可以得出来一模一样的随机数序列。因为算法和入参都确定了。

实际上伪随机算法如果保证均匀分布,而且随机数的种子依赖一些环境上面的不确定的值的话,还是让人感觉到和真随机差不多的。


因为电脑里面产生随机数的函数大致是通过电脑某些元件的特征信息来产生,例如CPU序号,网卡Mac地址,时钟当前读数等,再加上每次参与生成的seed种子参数不同,就会生成不同的数。这种算法最大限度地保证了不同计算机上或者相同计算机在不同时间上生成不同的数。但是最关键的事情来了,这个随机数生成算法其实算出的是一个确定数,或者说是一个可预知的数。只要算法所依赖的特征一样,例如CPU序号,Mac地址,时钟读数等等,在相同seed情况下,总是得到相同值。这样就不是随机数了,而是确定数,因此叫伪随机数。最后总结一下,rand()等随机函数产生的数只能保证在不同机器,不同时间等特征要素不同时得到不同的值。而这些特征在计算机世界里是很容易伪造或者设置为相同的。同样的情况是UUID的生成函数,虽然足够大,号称可以标注全宇宙的每一个原子,但在人为或者巧合情况下,是很容易重复的。


家用电脑没有设置随机数字发生器电路,所得随机数是通过查询一张随机数表得出的,入口就是所谓的种子,一般用时间秒作为种子,保证短时间内不重复。但这个查表得出的随机数显然不够随机,你可以用一个循环连续调用rand()函数,会发现短时间内得到的值重复概率极大。而中间插一个延时函数后就能显著降低重复概率。


原始地址:/shenghuo/16955.html