关于随机数

在使用计算机的过程中,有很多情况会接触到随机数。比如,播放器的随机播放、游戏中的随机事件、等等。尽管这些东西都号称随机,但是用户体验总是会出些问题。比如,选择了随机播放,放来放去却总是那几首歌。又比如,游戏中的随机事件,总能被有经验的玩家猜中七八成。这是怎么回事呢?

这个问题可能牵扯到的范围实在太大了:程序是否实现了随机?人的经验产生了多大作用?……甚至于,宇宙中是否存在随机?(如果宇宙中的一切都是由物质构成的,并且物质的运动遵循固定的规律,那么宇宙中一切事物的发展轨迹就已经注定了。这就是所谓的“宿命论”。)

就我目前的理解而言,只能用“伪随机”来解释这个问题:计算机产生的随机数并不是真正的随机数。

在计算机中,经典的随机数产生算法是给定一个函数y=f(x),每个随机数都是通过它进行一次迭代而产生的。函数f(x)的迭代过程如下:
x0, x1=f(x0), x2=f(x1), ..., xn=f(xn-1), ...
第0个随机数x0被称为种子。

在标准C中,提供函数srand()用于设置种子、rand()用于进行一次迭代,产生一个随机数。

很显然,在种子确定、迭代函数确定的情况下,迭代序列中的每一个xn都是确定的。这种算法完全不存在随机性。但是,这样的算法为什么能够用于生成随机数呢?

通过某个函数式进行迭代,当迭代次数充分大时,迭代序列可能有几种结果:
1、收敛;
2、出现周期性重复;
3、没有规律、杂乱无章,称之为混沌;

而随机数算法所需要的就是“混沌”这个结果,为此,迭代函数是精心选择的。这时候,迭代序列中的每一个xn杂乱无章地分布在某一区间中。在没有人知道迭代函数的情况下,姑且可以认为迭代序列是随机的。

可见,随机函数生成的随机数与真正的随机还是有很大差别的。

在C中,每次执行程序时,rand()都会生成相同的随机数序列。所以,一定要通过srand()来设置不同的种子。
有人认为,尽管随机数生成算法是“伪随机”的,但是我们可以给它设置一个随机的种子,使它产生的随机数真正随机。
但是这显然是不对的,种子和迭代函数都已经确定了,今后将要产生的数数也都已经注定了。这样的数据能称得上随机吗?
所以,通过一些客观因素(比如时间)来设置种子,可以提升随机数生成函数的表现,但是并不能改变它“伪随机”的本质。

那么,计算机能不能产生真正的随机数呢?其实,linux上有个叫/dev/random的文件,就能做到真正的随机。

/dev/random是linux内核创建的一个设备文件,每次读取这个文件,内核会输出一个随机串。
这个随机串从哪里来呢?其来源主要是外设中断。有这样一些外部设备,它们产生的中断是随机的。比如网卡,它接收到数据而产生中断的时刻基本上就是随机的。哪怕你刻意在某一时刻向网卡发送一个报文,网卡产生中断的时刻也是很不确定的。因为报文在传输过程中将受到传输介质的影响、网卡可能先收到了别人发送的报文、网卡收到报文后也不确定要等待多少时间CPU才进入中断(中断是不能中断正在执行的指令的)。所以,除非是刻意制造的实验环境,否则可以认为这一类外设能够提供随机的数据。

这些随机数据被称为“熵”,内核它们存储在“熵”池中。它在每次有新数据进入时,内核还需要做一些处理,取出数据中真正随机的那一部分(比如以网卡中断的时间为随机数据,那么“年月日”等信息显然不是随机的),然后进行一些数学变换,以便保存和输出。

实际使用中可能出现“熵”供小于求的情况,那么读/dev/random时,熵池为空,进程就要被阻塞,以等待下一个熵。于是内核又提供了另外一个文件/dev/urandom,作为折衷,如果熵池已经读空了,则产生伪随机数。

但是,从目前常用的这些软件来看,使用真随机的估计并不多。

时间: 2024-12-31 10:24:08

关于随机数的相关文章

c++-怎样产生同时两个随机数

问题描述 怎样产生同时两个随机数 我想做两个随机数的乘法,但不知道怎么才能同时产生两个随机数,求各位帮忙 解决方案 没有必要所谓同时产生.你前后产生2个就可以了. 解决方案二: 为什么要同时生成?分两次srand就可以了 解决方案三: c++估计没有这么智能,但是又种软件叫labview的编程语言,可以让2个线程运行在两个核上分别产生随进数,然后用两个线程产生的结果来相乘.本人有段时间不搞c++不知道线程有没有什么法子能让两个线程运行在2个核上 解决方案四: 当你在同一单线程程序里,怎么会同时呢

用C#生成不重复的随机数

对于随机数,大家都知道,计算机不可能产生完全随机的数字,所谓的随机数发生器都是通过一定的算法对事先选定的随机种子做复杂的运算,用产生的结果来近似的模拟完全随机数,这种随机数被称 作伪随机数.伪随机数是以相同的概率从一组有限的数字中选取的.所选数字并不具有完全的随机性,但是从实用的角度而言,其随机程度已足够了.伪随机数的选 择是从随机种子开始的,所以为了保证每次得到的伪随机数都足够地"随机",随机种子的选择就显得非常重要.如果随机种子一样,那么同一个随机数发生器产生 的随机数也会一样.一

shell如何生成指定范围随机数与随机字符串

1.使用系统的 $RANDOM 变量 fdipzone@ubuntu:~$ echo $RANDOM 17617 $RANDOM 的范围是 [0, 32767] 如需要生成超过32767的随机数,可以用以下方法实现. 例:生成400000~500000的随机数 #!/bin/bash function rand(){ min=$1 max=$(($2-$min+1)) num=$(($RANDOM+1000000000)) #增加一个10位的数再求余 echo $(($num%$max+$min

MySQL随机数的实现

SELECT FLOOR(7 + (RAND() * 6)); 在一个范围随机产生 一个数字 ------------------------------------------------------- 有朋友问到如何在mysql中使用随机数   如何写一个语句能一下更新几百条MYSQL数据! 需要测试MYSQL数据库,里面有一个上万条数据的数据库,如何写一个PHP文件一下每次更新几百条信息,我都是写一个循环一次更新一条信息,这样我知道用WHILE写就可以了,要是一次更新好比100条数据改如何

ASP的随机数的应用技术

随机 关于随机数,请参看以下资料: Rnd 函数 描述 返回一个随机数. 语法 Rnd[(number)] number 参数可以是任意有效的数值表达式. 说明 Rnd 函数返回一个小于 1 但大于或等于 0 的值. number 的值决定了 Rnd 生成随机数的方式: 如果 number 为 Rnd 生成 小于零 每次都相同的值,使用 number 作为种子. 大于零 序列中的下一个随机数. 等于零 最近生成的数. 省略 序列中的下一个随机数. 因每一次连续调用 Rnd 函数时都用序列中的前一

Javascript 生成指定范围数值随机数 By shawl.qiu

javascript|随机 说明:俺本来以为 Js 的随机数应该没啥, 查查手册就得了. 查手册后才知道, 介绍的信息少得可怜呐, 没有介绍生成 m-n 范围的随机数..., 就只是给你一个 Math.random() 了事. 不过经过俺的小小努力之后, 终于让俺摸着门道喽, 问题也就理所当然滴解决掉.  然后就写了个公式, 这样应该可以消失掉这个用法了, 公式: 1. 从1开始 至 任意值linenum parseInt(Math.random()*上限+1); 2. 从任意值开始 至 任意值

生成任意位随机数的函数

函数|随机 生成任意位随机数的函数'strLong是随机数字的位数,数字型Function rndNum (strLong) Dim temNum Randomize Do While Len(RndNum) < strLong temNum=CStr(Chr((57-48)*rnd+48)) RndNum=RndNum&temNum loopEnd Function

J2ME中随机数字处理全攻略

攻略|随机|随机数字 在程序中生成随机数字,用处比较,如人工智能领域等等,这里对于在J2ME中生成随机数的操作进行一个简单的整理,希望对大家能有帮助.       J2ME和J2SE不同,不能使用Math类的random来生成随机数字,只能使用java.util包的Random类来生成随机数字.       1.创建Random类型的对象:       Random random = new Random();Random random = new Random(10010010);以上两种是创

用ASP随机产生随机数

各位好今天我要告诉大家的是如何用ASP产生随机数.大家都知道大多数网站注册后 提供用户名和一个随机密码,但这个密码是如何产生的,现在我就向大家来介绍一下 请看下面的例子,用户可自行增加或减少随机的字符或数量. <%Function gen_key(digits) 'Create and define arraydim char_array(50)char_array(0) = "0"char_array(1) = "1"char_array(2) = &quo

正态分布的随机数发生器 in C#

随机 Box 和 Muller 在 1958 年给出了由均匀分布的随机变量生成正态分布的随机变量的算法.设 U1, U2 是区间 (0, 1) 上均匀分布的随机变量,且相互独立. 主要参考<Numerical Recipes in C++ 2/e>p.292-p.294 和<Simulation Modeling and Analysis 3/e>p.465-p.466. Box 和 Muller 在 1958 年给出了由均匀分布的随机变量生成正态分布的随机变量的算法.设 U1,