VC获取一定范围内的随机数
一、C++中不能使用random()函数random函数不是ANSIC标准,不能在
gcc,vc等编译器下编译通过。可改用C++下的rand函数来实现。1、C++标准函
数库提供一随机数生成器rand,返回0-RAND_MAX之间均匀分布的伪随机整数。
RAND_MAX必须至少为32767。rand()函数不接受参数,默认以1为种子(即起始
值)。随机数生成器总是以相同的种子开始,所以形成的伪随机数列也相同,失
去了随机意义。(但这样便于程序调试)
2、C++中另一函数srand(),可以指定不同的数(无符号整数变元)为种子。
但是如果种子相同,伪随机数列也相同。一个办法是让用户输入种子,但是仍
然不理想。
3、比较理想的是用变化的数,比如时间来作为随机数生成器的种子。time
的值每时每刻都不同。所以种子不同,所以,产生的随机数也不同。
//C++随机函数(VCprogram)
#includestdio.h
#includeiostream
#includetime.husingnamespacestd;
#defineMAX100intmain(intargc,char*argv)
{srand((unsigned)time(NULL));//srand()函数产生一个以当前时间开始
的随机种子.应该放在for等循环语句前面不然要很长时间等待
for(inti=0;i10;i++)
coutrand()%MAXendl;//MAX为最大值,其随机域为0~MAX-1return0;
二、rand()的用法
rand()不需要参数,它会返回一个从0到最大随机数的任意整数,最大随
机数的大小通常是固定的一个大整数。这样,如果你要产生0~10的10个整数,
可以表达为:
intN=rand();
这样,N的值就是一个0~10的随机数,如果要产生1~10,则是这样:
intN=1+rand();
总结来说,可以表示为:
a+rand()%n
其中的a是起始值,n是整数的范围。a+rand()%(b-a+1)就表示a~b之间
的一个随机数若要0~1的小数,则可以先取得0~10的整数,然后均除以10即
可得到随机到十分位的10个随机小数,若要得到随机到百分位的随机小数,则
需要先得到0~100的10个整数,然后均除以100,其它情况依
此类推。
通常rand()产生的随机数在每次运行的时候都是与上一次相同的,这是有
意这样设计的,是为了便于程序的调试。若要产生每次不同的随机数,可以使
用srand(seed)函数进行随机化whatsapp网页版,随着seed的不同,就能够产生不同的随机数。
如大家所说,还可以包含time.h头文件,然后使用srand(time(0))来使
用当前时间使随机数发生器随机化,这样就可以保证每两次运行时可以得到不
同的随机数序列(只要两次运行的间隔超过1秒)。
要怎么样才能真正产生有效的随机数?
工作原理如下
1)首先给srand()提供一个种子,它是一个unsignedint类型,其取值范
围从0~65535;
2)然后调用rand(),它会根据提供给srand()的种子值返回一个随机数(在
0到32767之间)
3)根据需要多次调用rand(),从而不间断地得到新的随机数;
4)无论什么时候,都可以给srand()提供一个新的种子,从而进一步"随机
化"rand()的输出结果。
因为srand()函数是一个随机数产生函数,其意思就是指C语言里的随机
数都是由它来控制产生的!如果在应用srand()函数之前就用随机函数rand(),
则相当于使用了srand(1);
而将srand((unsigned)time(NULL));这条语句放在了for循环里,即是
用了srand((unsigned)time(0));故此句语句不变的话,产生的随机数就不变!
C语言随机函数总结)rand()函数:
原型:intrand(void)
功能:产生从0到RAND_MAX(0x7fff)之间的随机数。
头文件:stdlib.h
例:
#includestdio.h
#includestdlib.hintmain()
intk;
k=rand();
printf("%d\n",k);
return0;
(2)srand()函数:
原型:voidsrand(unsignedseed)
功能:产生随机数的起始发生数据,和rand函数配合使用
头文件:stdlib.htime.h
例:
#includestdio.h
#includestdlib.h
#includetime.hvoidmain()
time_tt;
srand((unsigned)time(&t));
printf("%d\n",rand()0);
这时运行程序,会发现每次产生的随机数都不一样。这是因为这里采用了
时间作为种子,而时间在每时每刻都不相同,所以就产生了"随机"的随机数了。
所以,要想产生不同的随机数,在使用rand之前需要先调用srand。
伪随机数生成及在VC++中的实现
摘要伪随机数在计算机软件设计中有很广泛的用途。本文介绍了基于数学
方法的利用计算机产生伪随机数的一种方法,即线性同余法,任何伪随机数的
产生都是运用递推的原理来生成的。以及在VisualC++环境中产生伪随机数的
两个重要函数,rand和srand函数,正确地使用这两个函数是产生性能良好的
伪随机数的关键,最后介绍了利用伪随机数生成技术在MFC中生成基于C/S模
式应用程序的随机校验码以及利用一种软件工具ImagePassword产生随机密码。
关键词伪随机数生成;线性同余法;VisualC++;随机校验码
为追求真正的随机序列,人们曾采用很多种原始的物理方法用于生成一定
范围内满足精度(位数)的均匀分布序列,其缺点在于:速度慢、效率低、需占
用大量存储空间且不可重现等。为满足计算机模拟研究的需求,人们转而研究
用算法生成模拟各种概率分布的伪随机序列。伪随机数是指用数学递推公式所
产生的随机数。从实用的角度看,获取这种数的最简单和最自然的方法是利用
计算机语言的函数库提供的随机数发生器。典型情况下,它会输出一个均匀分
布在0和1区间内的伪随机变量的值。其中应用的最为广泛、研究最彻底的一
个算法即线性同余法。
线性同余法LCG(LinearCongruenceGenerator)
选取足够大的正整数M和任意自然数n0,a,b,由递推公式:
ni+1=(af(ni)+b)mod Mi=0,1,…,M-1
生成的数值序列称为是同余序列。当函数f(n)为线性函数时,即得到线性
同余序列:
ni+1=(a*ni+b)mod Mi=0,1,…,M-1
以下是线性同余法生成伪随机数的伪代码:
Random(n,mwhatsapp网页版,seedwhatsapp登录,a,b)
r0=seed;
for(i=1;i=n;i++)
ri=(a*ri-1+b)mod m
其中种子参数seed 可以任意选择,常常将它设为计算机当前的日期或者时
间;m 是一个较大数,可以把它取为2w,w 是计算机的字长;a 可以是0.01w 和
0.99w 之间的任何整数。
应用递推公式产生均匀分布随机数时,式中参数n0,a,b,M 的选取十分
重要。
例如,选取 M=10,a=b=n0=7,生成的随机序列为{6,9,0,7,6,9,…},
周期为4。
取 M=16,a=5,b=3,n0=7,生成的随机序列为{6,1,8,11,10,5,12,
15,14,9,0,3,2,13,4,7,6,1…},周期为16。
取M=8,a=5,b=1,n0=1,生成的随机序列为{6,7,4,5,2,3,0,1,
6,7…},周期为8。
Visual C++中伪随机数生成机制
用VC 产生随机数有两个函数,分别为rand(void)和srand(seed)。rand()
产生的随机整数是在0~RAND_MAX 之间平均分布的,RAND_MAX 是一个常量(定义
为:#define RAND_MAX 0x7fff)。它是short 型数据的最大值,如果要产生一
个浮点型的随机数,可以将rand()/1000.0,这样就得到一个0~32.767 之间平
均分布的随机浮点数。如果要使得范围大一点,那么可以通过产生几个随机数
的线性组合来实现任意范围内的平均分布的随机数。
其用法是先调用srand 函数,如
srand((unsigned)time(NULL))
这样可以使得每次产生的随机数序列不同。如果计算伪随机序列的初始数
值(称为种子)相同,则计算出来的伪随机序列就是完全相同的。要解决这个问
题,需要在每次产生随机序列前,先指定不同的种子,这样计算出来的随机序
列就不会完全相同了。以time 函数值(即当前时间)作为种子数,因为两次调用
rand 函数的时间通常是不同的,这样就可以保证随机性了。也可以使用srand
函数来人为指定种子数。
分析以下两个程序段,
程序段1:
//包含头文件
void main(){
int count=0;
for(int i=0;i 10;i++){
srand((unsigned)time(NULL));
count++;
cout"No""="RAND()"?;
程序段1 中由于将srand()函数放在循环体内,而程序执行的CPU 时间较
快,调用time 函数获取的时间精度却较低(55ms),这样循环体内每次产生随机
数用到的种子数都是一样的,因此产生的随机数也是一样的。而程序段2 中第
1 次产生的随机数要用到随机种子,以后的每次产生随机数都是利用递推关系
得到的。
基于MFC 的随机校验码生成
Web 应用程序中经常要利用到随机校验码,校验码的主要作用是防止黑客
利用工具软件在线破译用户登录密码,校验码、用户名、密码三者配合组成了
进入Web 应用系统的钥匙。在利用VC 开发的基于客户机/浏览器
(Client/Server)模式的应用软件系统中,为了防止非法用户入侵系统,通常也
要运用随机校验码生成技术。
本实现要用到以上介绍到的伪随机数生成技术。校验码数据将以16 进制码
方式显示。主要代码如下:
void CRandompasswordDlg:OnCreatekey(){
int RanCheckNum=0;
char out={0};
char keytemp={0};
memset(out,0x30,18);
srand((unsigned)timeGetTime());//产生随机数种子
for(int i=0;i 6;i++){
RanCheckNum=rand();//产生随机数
_itoa(RanCheckNum,keytemp,16);//将随机数转换成16 进制
memcpy(&out,keytemp,strlen(keytemp));
out=0x00;
strcpy(m_key.GetBuffer(18),out);
UpdateData(FALSE);
运行结果如图1 所示:
图1 利用伪随机数生成随机校验码
程序运行时,由于每一次点击"产生随机校验码"的系统时间不同,生成随
机数的种子就不一样,因此产生的随机数也是不一样的,从而保证了校验码生
成的随机性。
利用ImagePassword 工具产生随机密码
ImagePassword 提供一个可选择的图形阵列,通过随机改变图形阵列中的
阵点图形来产生随机密码。当随机点击图象阵列中的图象阵点,该阵点中的图
象发生变化。其运行界面如图2 所示:
图2 ImagePassword 运行界面
点击OK 按钮后所产生的随机密码如图3 所示:
图3 ImagePassword 运行结果
ImagePassword 产生的密码的随机性依赖于用户对图象阵列中阵点图象的
随机选择,一般来说用户在图象阵列中随机点击鼠标的次数越多,最后产生的
密码的随机性越强。
结束语
伪随机数在不同的软件系统中都得到了很广泛的应用,如何选择随机数生
成种子使得生成的伪随机数性能更佳是软件设计者追求的目标之一。本文提到
了利用系统时间作为种子参数在一定条件下可以满足软件的随机性需要。利用
所产生的随机数在游戏编程,如扑克类游戏中的随机发牌,俄罗斯方块的随机
生成等等其他应用中都起到很重要的作用。
版权声明
本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。