计算机随机数初探
来源:互联网 发布:mac excel求和快捷键 编辑:程序博客网 时间:2024/06/16 04:22
研究过随机数吗?我们都知道电脑里面的随机数其实只是看上去是随机的,产生的过程都是确定的。如果我们有一定的破解能力,我们就能预测得到,下一次机器产生的随机数是哪个值。
在c++编程中,我们总要放一个随机种子,这个种子一般是当前时间,这样我们可以看到每次调用的随机数工厂产生的数值是不一样的。如果我们把随机数种子设定为一个特定的数,那么产生的随机数也是固定的。这样有一个好处,就是方便调试,因为调试的时候肯定不希望每次运行的结果都不一样。
但是在真正的计算中我们是希望随机数尽可能真的是随机出来的。所以又两种方法
1用更好的随机方法。算法没有最好的方法,就像排序算法一样,只有适合某种情形。
2用物理硬件:原子衰减检测。电路中量子力学噪声
0先告诉一个惊人的事实
c++ rand() 产生的随机数在[0,RAND_MAX]之间的一个整数.这是一个均匀分布.如果我们希望产出[a,b]之间的随机数通常会这么处理
(rand()%(b-a+1))+a
这种算法导致不是所以的值都是等概率出现的。只有当(b-a+1)可以整除RAND_MAX+1时才可以.假设RAND_MAX为32767那么生成[0
32766]的时候0的概率是其他值出现概率的两倍.一个解决的办法就是先成[0,1]之间的一个值,在放缩到[a,b]区间上.
double v=(double)rand()/RAND_MAX;
result=(int)(V*(b-a))+a;//这里一个书中给的代码是(V*(b-a+1))+a,我认为是错的,因为如果v=1的时候产生的值是b+1,如果我错了请务必告诉我
1介绍一个常用的分布,
如果我们希望以高斯分布的概率产生随机值,让更多的值不要偏离中心太多,那么该怎么做?
一个简单的方法(其实不简单)用randf()产生[0,1]之间的实数随机数,这个randf要自己编程,然后做BOX-Muller变换,这样可以产生两个随机数(买一赠一),不知道那个鸟变换没关系,我也不知道.
那么问题来了。如何产生其他的分布?这个要用到中心极限定理。读者可以自己看看资料
2介绍几个不能用于加密的随机数产生算法
之所以说不能用于加密,是应用这种随机数可能使信息被破解的可能性大。
a线性同余生成器
x_(n+1)=(a*x_(n)+b)%m
其中x_(n+1)就是新产生的随机数,x_(n)是之前的数.n是零的话那个就是随机种子吧!a,b是一个参数,m是一个2的次方数(这样便于取余).vb6中这个算法的参数是m=2^24,a=16598013,b=12820163.
b截断线性同余生成器
先用a算法产生一个随机数,然后计算floor[x_(n+1)/k]。k是2的乘方把这个数返回。
当然还有其他的方法,线性反馈移位寄存器算法,逆同余生成器,滞后斐波那契生成器,元胞自动机,线性回归生成器,马特赛旋转法,well算法。
3可用于加密的随机数
blum blum shub算法。isacc,isacc+。这些都是算法,需要者自行百度。
/dev/random
这个是linux上的一个随机源,他基于系统熵返回一个随机数,可以看成一个真正的随机数.因为产生随机数需要系统收集信息,在系统没有足够信息的时候会造成阻塞。
微软的CryptGenRandom
这个也可是被视为真正的随机数,虽然未开源。
在c++编程中,我们总要放一个随机种子,这个种子一般是当前时间,这样我们可以看到每次调用的随机数工厂产生的数值是不一样的。如果我们把随机数种子设定为一个特定的数,那么产生的随机数也是固定的。这样有一个好处,就是方便调试,因为调试的时候肯定不希望每次运行的结果都不一样。
#include<iostream>#include<ctime>#include <cstdlib>using namespace std;int main(){ srand(time(0));//time(0)返回当前时间传到srand里面做随机种子 int x=rand(); }
但是在真正的计算中我们是希望随机数尽可能真的是随机出来的。所以又两种方法
1用更好的随机方法。算法没有最好的方法,就像排序算法一样,只有适合某种情形。
2用物理硬件:原子衰减检测。电路中量子力学噪声
0先告诉一个惊人的事实
c++ rand() 产生的随机数在[0,RAND_MAX]之间的一个整数.这是一个均匀分布.如果我们希望产出[a,b]之间的随机数通常会这么处理
(rand()%(b-a+1))+a
这种算法导致不是所以的值都是等概率出现的。只有当(b-a+1)可以整除RAND_MAX+1时才可以.假设RAND_MAX为32767那么生成[0
32766]的时候0的概率是其他值出现概率的两倍.一个解决的办法就是先成[0,1]之间的一个值,在放缩到[a,b]区间上.
double v=(double)rand()/RAND_MAX;
result=(int)(V*(b-a))+a;//这里一个书中给的代码是(V*(b-a+1))+a,我认为是错的,因为如果v=1的时候产生的值是b+1,如果我错了请务必告诉我
1介绍一个常用的分布,
如果我们希望以高斯分布的概率产生随机值,让更多的值不要偏离中心太多,那么该怎么做?
一个简单的方法(其实不简单)用randf()产生[0,1]之间的实数随机数,这个randf要自己编程,然后做BOX-Muller变换,这样可以产生两个随机数(买一赠一),不知道那个鸟变换没关系,我也不知道.
float x1,x2,w,y1,y2;do{ x1=2.0*randf()-1.0; x2=2.0*randf()-1.0; w=x1*x1+x2*x2;}while(w>=1.0);w=sqrt((-2.0*log(w))/w);y1=x1*w;y2=x2*w;
那么问题来了。如何产生其他的分布?这个要用到中心极限定理。读者可以自己看看资料
2介绍几个不能用于加密的随机数产生算法
之所以说不能用于加密,是应用这种随机数可能使信息被破解的可能性大。
a线性同余生成器
x_(n+1)=(a*x_(n)+b)%m
其中x_(n+1)就是新产生的随机数,x_(n)是之前的数.n是零的话那个就是随机种子吧!a,b是一个参数,m是一个2的次方数(这样便于取余).vb6中这个算法的参数是m=2^24,a=16598013,b=12820163.
b截断线性同余生成器
先用a算法产生一个随机数,然后计算floor[x_(n+1)/k]。k是2的乘方把这个数返回。
当然还有其他的方法,线性反馈移位寄存器算法,逆同余生成器,滞后斐波那契生成器,元胞自动机,线性回归生成器,马特赛旋转法,well算法。
3可用于加密的随机数
blum blum shub算法。isacc,isacc+。这些都是算法,需要者自行百度。
/dev/random
这个是linux上的一个随机源,他基于系统熵返回一个随机数,可以看成一个真正的随机数.因为产生随机数需要系统收集信息,在系统没有足够信息的时候会造成阻塞。
微软的CryptGenRandom
这个也可是被视为真正的随机数,虽然未开源。
0 0
- 计算机随机数初探
- 随机数初探
- 计算机中的随机数
- 随机数的计算机生成
- 猜计算机随机数
- 计算机仿生物学初探
- 计算机集群:初探
- 计算机为什么能生成随机数?
- 计算机中随机数的生成
- 简述计算机随机数生成原理
- 计算机输出不同的随机数
- 计算机生成随机数的一种方法
- 计算机生成真随机数原理及实现
- 计算机的随机数函数和产生原理
- 中职非计算机专业《计算机应用基础》教学初探
- 中职非计算机专业《计算机应用基础》教学初探
- 中职非计算机专业《计算机应用基础》教学初探
- 计算机视觉笔记(一) 初探计算机视觉
- NoSql之旅-mongoDB shell命令总结
- const成员函数
- SQL SERVER 2008 利用发布订阅方式实现数据库同步
- mysql涉及多个字段的模糊查询
- C语言DFS(7)___单词拼接(NYoj 99)
- 计算机随机数初探
- 剑指Offer之 - 二叉树的深度
- 已知某系统在通信联络中只可能出现8种字符,其概率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试编写算法求其赫夫曼编码。
- 黑马程序员—— JDK1.5,for循环的新写法
- android xlmns:android
- 【机房重构】——存储过程遇到的问题
- matlab一维搜索,用进退法确定搜索区间
- Ubuntu 12.04 64bit 安装 openedx
- 韩岩___第8课___《linux内核分析》MOOC课