为追求真正的随机序列,人们曾采用很多种原始的物理方法用于生成一定范围内满足精度(位数)的均匀分布序列,其缺点在于:速度慢、效率低、需占用大量存 储空间且不可重现等。为满足计算机模拟研究的需求,人们转而研究用算法生成模拟各种概率分布的伪随机序列。伪随机数是指用数学递推公式所产生的随机数。从 实用的角度看,获取这种数的最简单和最自然的方法是利用计算机语言的函数库提供的随机数发生器。典型情况下,它会输出一个均匀分布在0和1区间内的伪随机 变量的值。其中应用的最为广泛、研究最彻底的一个算法即线性同余法。
线性同余法LCG(Linear Congruence Generator)
选取足够大的正整数M和任意自然数n0,a,b,由递推公式:
ni+1=(af(ni)+b)mod M i=0,1,…,M-1 |
生成的数值序列称为是同余序列。当函数f(n)为线性函数时,即得到线性同余序列:
ni+1=(a*ni+b)mod M i=0,1,…,M-1 |
以下是线性同余法生成伪随机数的伪代码:
Random(n,m,seed,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"<<count<<"="<<rand()<<" "; if (!(count%5)) cout <<endl; } } |
程序段2:
//包含头文件 void main() { int count=0; srand((unsigned)time(NULL)); for (int i=0;i <10;i++){ count++; cout <<"No"<<count<<"="<<rand()<<" "; if (!(count%5)) cout <<endl; } } |
程序段1的运行结果为:
No1=9694 No2=9694 No3=9694 No4=9694 No5=9694 No6=9694 No7=9694 No8=9694 No9=9694 No10=9694 |
程序段2的运行结果为:
No1=10351 No2=444 No3=11351 No4=3074 No5=21497 No6=30426 No7=6246 No8=24614 No9=22089 No10=21498 |
可以发现,以上两个程序段由于随机数生成时选择的种子的不同,运行的结果也不一样。rand()函数返回随机数序列中的下一个数(实际上是一个伪随 机数序列,序列中的每一个数是由对其前面的数字进行复杂变换得到的)。为了模仿真正的随机性,首先要调用srand()函数给序列设置一个种子。为了更好 地满足随机性,使用了时间函数time(),以便取到一个随时间变化的值,使每次运行rand()函数时从srand()函数所得到的种子值不相同。伪随 机数生成器将作为"种子"的数当作初始整数传给函数。这粒种子会使这个球(生成伪随机数)一直滚下去。
程序段1中由于将srand()函 数放在循环体内,而程序执行的CPU时间较快,调用time函数获取的时间精度却较低(55ms),这样循环体内每次产生随机数用到的种子数都是一样的, 因此产生的随机数也是一样的。而程序段2中第1次产生的随机数要用到随机种子,以后的每次产生随机数都是利用递推关系得到的。
基于MFC的随机校验码生成
Web应用程序中经常要利用到随机校验码,校验码的主要作用是防止黑客利用工具软件在线破译用户登录密码,校验码、用户名、密码三者配合组成了进入Web 应用系统的钥匙。在利用VC开发的基于客户机/浏览器(Client/Server)模式的应用软件系统中,为了防止非法用户入侵系统,通常也要运用随机 校验码生成技术。
本实现要用到以上介绍到的伪随机数生成技术。校验码数据将以16进制码方式显示。主要代码如下:
void CRandompasswordDlg::OnCreatekey() { int RanCheckNum = 0; char out[25]={0}; char keytemp[5]={0}; memset(out,0x30,18); srand((unsigned)timeGetTime());//产生随机数种子 for(int i=0;i <6;i++){ RanCheckNum = rand();//产生随机数 _itoa(RanCheckNum,keytemp,16);//将随机数转换成16进制 memcpy( &out[i*4],keytemp,strlen(keytemp)); } out[24]=0x00; strcpy(m_key.GetBuffer(18),out); UpdateData(FALSE); } |
运行结果如图1所示:
 图1 利用伪随机数生成随机校验码
|
程序运行时,由于每一次点击"产生随机校验码"的系统时间不同,生成随机数的种子就不一样,因此产生的随机数也是不一样的,从而保证了校验码生成的随机性。
利用ImagePassword工具产生随机密码 ImagePassword提供一个可选择的图形阵列,通过随机改变图形阵列中的阵点图形来产生随机密码。当随机点击图象阵列中的图象阵点,该阵点中的图象发生变化。其运行界面如图2所示:
 图2 ImagePassword运行界面
|
点击OK按钮后所产生的随机密码如图3所示:
 图3 ImagePassword运行结果
|
ImagePassword产生的密码的随机性依赖于用户对图象阵列中阵点图象的随机选择,一般来说用户在图象阵列中随机点击鼠标的次数越多,最后产生的密码的随机性越强。
结束语 伪随机数在不同的软件系统中都得到了很广泛的应用,如何选择随机数生成种子使得生成的伪随机数性能更佳是软件设计者追求的目标之一。本文提到了利用系统 时间作为种子参数在一定条件下可以满足软件的随机性需要。利用所产生的随机数在游戏编程,如扑克类游戏中的随机发牌,俄罗斯方块的随机生成等等其他应用中 都起到很重要的作用。
此文章来源:http://dotnet.chinaitlab.com/VCNET/714808.html
分享到:
相关推荐
在PHP编程中,批量生成图片缩略图是一个常见的需求,特别是在构建论坛或社交媒体平台时,为了提高用户体验,通常需要对用户上传的图片进行自动化处理,生成预览版本,即缩略图。本教程将深入探讨如何使用PHP实现这一...
标题中的“论坛转帖工具.rar”表明这是一个用于在论坛之间转移帖子的软件工具,通常用于帮助用户方便地将一个论坛的帖子内容复制到另一个论坛,可能是为了分享信息、讨论或保存重要的帖子。这类工具可能包括自动抓取...
【贴吧转帖工具】是一种专为百度贴吧用户设计的便捷工具,主要用于提高用户在贴吧中的互动效率。通过这款工具,用户可以实现一键转帖和一键8经验签到的功能,极大地简化了传统操作流程,节省了用户的时间,提升了...
UBB论坛转帖圣手.exeUBB论坛转帖圣手.exe
这样,新插入的转帖按钮将出现在已生成的页面中,等待用户使用。 该插件的工作原理主要是通过JavaScript(`copyto.js`)实现用户界面的交互,当用户点击转帖按钮时,会触发PHP脚本(`copyto.php`)。`copyto.php`...
在IT行业中,编辑人员在处理图像或视频时经常会遇到水印问题。水印可能是他人版权的标识,也可能是不希望展示的信息,去除水印成为了一项必要的技能。本篇文章将详细探讨“编辑人员转帖去水印工具”,并介绍如何使用...
3.批量随机新增文字(新增内容可自定义,从而实现伪原创) 4.cookie记录替换和新增关键词(避免每次打开转帖工具都要输入繁琐的替换关键词) 5.新增按颜色屏蔽干扰码 6.新增减少缩进以及优化了首行缩进 7.优化一些小...
4. **日志记录**:为了便于管理和跟踪,插件可能还会记录转帖操作,生成日志供管理员查看,以便了解转帖历史和排查问题。 5. **兼容性**:作为正式版插件,它应该经过了严格的测试,与 PHPwind 7.5 版本保持良好的...
"一键转帖功能插件 for 帝国CMS v1.0.rar" 是一个专为帝国CMS设计的扩展工具,其主要目标是简化用户在网站上分享内容的过程,提高用户体验。这个插件允许用户轻松地将网站上的文章或信息复制并转发到其他平台,如...
标题和描述中的“世界编程大赛第一名写的程序”这一知识点,实际上指向了计算机科学与编程竞赛领域的一个重要概念:即在高水平的编程比赛中,优胜者所编写的代码往往蕴含着高级算法、数据结构以及编程技巧。...
3. 原创保护:在转帖时,可以进行必要的处理,如添加引用、链接原文,尊重原作者,避免侵犯版权。 三、使用注意事项 1. 法律合规:使用这类工具时,必须确保所发布的帖子内容合法,不侵犯他人权益,遵循网络道德...
- 在Delphi7中打开CE的源代码工程,编译生成新的EXE文件。 - 使用加花软件对生成的EXE文件进行混淆处理,增加其隐蔽性。 - 接着,使用加壳工具为加花后的程序再添加一层外壳,进一步隐藏其原始特征。 - 最后,...
HTML2UBBMaxcj 是一款专为Softii论坛设计的转帖工具,它主要用于将HTML格式的帖子内容转换成UBB代码,以便在论坛中更好地显示和分享。UBB(Universal BBCode)是一种轻量级的标记语言,常用于网络论坛,与HTML类似,...
标题中的“如何在不同的浏览器中打开控制台调试JS”是一个关于网页开发中JavaScript调试的关键话题。在现代Web开发中,浏览器的开发者工具是必不可少的工具,尤其是JavaScript控制台,它可以帮助开发者追踪错误、...
在这个案例中,生成器可能是一个模板或元编程工具,能根据输入的盘子数量自动生成对应的汉诺塔解法代码。 4. **递归算法**:在C#中实现汉诺塔问题通常涉及递归函数。递归是解决问题的一种方法,其中函数调用自身来...
转帖图片提取工具可以对论坛图片附件信息进行清除,只保留图片代码,操作很简单,推荐有需要转帖图片工具的朋友下载 转帖图片提取工具使用方法: 将IP138上处理过的东西复制到上方的编辑框内,点击只要图片,下面...
4. **数据处理和更新**:在`success`回调函数中,遍历返回的城市数据,动态生成`<option>`元素,并添加到城市选择器中。 ```javascript success: function(data) { var $citySelect = $('#city'); $citySelect....
2. **使用Word**:复制网页URL,然后在Word中打开,Word会下载网页内容,用户可以在Word中进行复制、编辑和保存。 3. **浏览器插件**:有些浏览器,如火狐,可以安装扩展程序(如Greasemonkey)来解除右键锁定。例如...
转帖PLCDCSFCS三大控制系统的特点和差异 PLC、DCS、FCS 三大控制系统是自动化技术中的热点,各有其特点和差异。下面对这三大控制系统的特点和差异进行分析。 1.PLC(Programmable Logic Controller) PLC 是一种...