摘 要 伪随机数在计算机软件设计中有很广泛的用途。本文介绍了基于数学方法的利用计算机产生伪随机数的一种方法,即线性同余法,任何伪随机数的产生都是运用递推的原理来生成的。以及在Visual C++环境中产生伪随机数的两个重要函数,rand和srand函数,正确地使用这两个函数是产生性能良好的伪随机数的关键,最后介绍了利用伪随机数生成技术在MFC中生成基于C/S模式应用程序的随机校验码以及利用一种软件工具ImagePassword产生随机密码。

   关键词 伪随机数生成;线性同余法;Visual C++;随机校验码

  为追求真正的随机序列,人们曾采用很多种原始的物理方法用于生成一定范围内满足精度(位数)的均匀分布序列,其缺点在于:速度慢、效率低、需占用大量存储空间且不可重现等。为满足计算机模拟研究的需求,人们转而研究用算法生成模拟各种概率分布的伪随机序列。伪随机数是指用数学递推公式所产生的随机数。从实用的角度看,获取这种数的最简单和最自然的方法是利用计算机语言的函数库提供的随机数发生器。典型情况下,它会输出一个均匀分布在0和1区间内的伪随机变量的值。其中应用的最为广泛、研究最彻底的一个算法即线性同余法。
网管网www_bitscn_com

  线性同余法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的选取十分重要。 网管有家bitscn.net

  例如,选取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函数来人为指定种子数。 网管u家www.bitscn.net
分析以下两个程序段,

  程序段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
中国网管论坛bbs.bitsCN.com

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次产生的随机数要用到随机种子,以后的每次产生随机数都是利用递推关系得到的。【转自www.bitsCN.com】

转载于:https://www.cnblogs.com/Aioria0622/archive/2008/12/03/1346518.html

在VC++中生成伪随机数祥解相关推荐

  1. 转;VC++中Format函数详解

    Format是一个很常用,却又似乎很烦的方法,以下是它的完整概貌,以供大家查询之用: 一.字符串 首先看它的声明:  function Format(const Format: string; con ...

  2. java邮件附件名称乱码_Javamail 中附件中文名字乱码祥解 (转)

    Javamail 中附件中文名字乱码祥解 (转)[@more@]现在研究JavaMail的人越来越多,现在我就谈谈在javamail中大家都会遇到的附件中文问题,由于sun的java的中文问题,导致当 ...

  3. Python中random模块生成随机数详解

    Python中random模块生成随机数详解 本文给大家汇总了一下在Python中random模块中最常用的生成随机数的方法,有需要的小伙伴可以参考下 Python中的random模块用于生成随机数. ...

  4. Linux操作系统中man命令的用法,Linux 系统中的MAN命令使用祥解

    Linux 系统中的MAN命令使用祥解 在使用Linux命令或程序的过程中,大家免不了要看看命令和程序的帮助文档.这就要使用到man命令.下面就man命令使用的方法具体说一下: 1.man 的使用语法 ...

  5. EasyJWeb Tools中代码自动生成引擎详解

    在EasyJWeb-0.6.0推出来以后,很多网友对其中的代码生成部分非常感兴趣,并来信问了一些如何使用easyjwebtools.如何支持多表生成.生成页面的定制.业务逻辑的定制等很多问题.下面以我 ...

  6. c 语言 多进程,VC++中进程与多进程管理的方法详解

    本文实例讲述了VC++中进程与多进程管理的方法,分享给大家供大家参考.具体方法分析如下: 摘要: 本文主要介绍了多任务管理中的多进程管理技术,对进程的互斥运行.子进程的创建与结束等作了较详细的阐述. ...

  7. c 语言字体怎么改,VC++中的字体设置方法详解

    VC++中static text字体改变 窗口都有2个和字体有关的函数:CWnd::GetFont()和SetFont(CFont*, BOOL); 1)CFont* pFont = m_static ...

  8. C/C++ 中生成特定范围内的随机数

    大家在写 C/C++ 程序时,难免会遇到要求获取某个范围内的随机数,我查阅了一些资料后,总结如下.本文分两部分,先介绍 C 语言中与随机数相关的两个函数 srand 和 rand,后介绍 C++ 中的 ...

  9. VC++中的char,wchar_t,TCHAR(转载)

    VC++中的char,wchar_t,TCHAR 大家一起做一个项目,经常发现有的人爱用strcpy等标准ANSI函数,有的人爱用_tXXXX函数,这个问题曾经搞的很混乱.为了统一,有必要把来龙去脉搞 ...

最新文章

  1. 递归函数 集合 列表 元组
  2. springboot-swagger2
  3. Vue引用其他组件,但组件某些部分不需要时的简单处理
  4. 单位矩阵的逆矩阵是它本身吗_矩阵运算、单位矩阵与逆矩阵(二)
  5. zabbix mysql设置中文乱码_解决zabbix监控因php问题导致图形界面中文乱码方法
  6. multipart/form-data;boundary=----WebKitFormBoundaryRAYPKeHKTYSNdzc1;charset=UTF-8‘ not supporte
  7. linux的df命令根目录,详细分析Linux df命令的使用方法
  8. 深度学习 deep learning 花书 pdf下载
  9. vue中 jsbarcode的使用技巧
  10. 10 个错过即损失的智能合约开发者工具
  11. python安装文件或目录损坏_文件或目录损坏且无法读取的解决办法
  12. 【Chrome插件】广告屏蔽神器 Adblock Plus使用教程
  13. 移动APP登录注册(vue+vant)
  14. u3m8缓存文件.ts合成mp4
  15. 武侠世界。。。。。。。。。
  16. 深度学习入门之如何制作npz、npy文件
  17. 解决问题 Warning: Can‘t perform a React state update on an unmounted compo
  18. pandas to_excel如何突破65535的长度限制?
  19. 实数加法 小数高精度加法 c++ vector实现
  20. chatgpt赋能python:Python程序员必知的Geany配置技巧

热门文章

  1. NDK error Error 126 make: *** Deleting file
  2. WinAPI: Ellipse - 绘制椭圆
  3. 很多想法、很多感慨。
  4. Linux用户和用户组管理常见问题
  5. 分析 C# 2.0 新特性 -- 范型(Generics)
  6. 阿里对大年龄清退的定义
  7. spark的三种运行模式以及yarn-client和yarn-cluster在提交命令上的区别
  8. mysql重置密码以及授予权限
  9. 线性代数导论5——SVD分解
  10. 纽约大学计算机和信息科学专业排名,纽约大学计算机科学与信息系统世界排名2018年最新排名第33(QS世界排名)...