随机数的产生原理与实现
随机数的产生原理与实现
下载本节例子程序和源代码 (3.91 KB)
随机数的产生在病毒中占有十分重要的地位,尤其是在变形引擎中,没有它就不成事了……因此,今天就让我们来探讨一下如何产生一个随机数。
首先值得说明的是,要产生一个随机数,方法有很多种,例如混沌和分形理论(原理比较复杂,但是公式却异常简单,将来有空的话我会介绍一下)……但是这些方法的缺点是计算难度大,需要花费的时间多,有没有一种实现起来比较简单的方法呢?
答案是肯定的。我们先来看一条数学公式:
Rand_Number = (Rand_Seed * X + Y) mod Z
利用这条公式,我们就可以生成一个伪随机数了。可是为什么是“伪随机数”呢?因为实际上要保证每次生成的随机数都不同,那是不太可能的,我们唯一能做到的只能是尽量使每次生成的数字与前面的不同,并且尽量使生成的数字均匀分布在指定的范围内。
上面的这条公式就能满足这两点。至于为什么……呵呵,我也不懂,因为它牵涉到十分复杂的数学求证过程,我们只需要知道如何应用就成了:
Rand_Seed 表示随机数种子,注意这个“种子”必须每次都不同,我们可以简单地利用 GetTickCount() 这个 API 来获得不同的数字,当然,你也可以用别的方法来取得,例如读取当前鼠标的坐标等等……
X、Y必须至少有一个为素数。什么叫素数?Hoho,让我们来翻翻小学课本……素数就是除了 1 和它本身,不能被其他数整除的数字。在这里我们可以简单地给 X、Y 赋值 23 和 7 ,其实别的素数也行,我只是随便取了这两个数字。
最后,Z 也应该是一个素数,这样才能保证产生的随机数能得到上限的值。不过我在实践中发现,这个 Z 不一定要准确地为素数。Why? I also don’t know...
总结一下,利用以上的公式,我们可以编写汇编代码如下:
iRand proc uses ecx edx first:DWORD, second:DWORD
invoke GetTickCount ; 取得随机数种子,当然,可用别的方法代替
mov ecx, 23 ; X = ecx = 23
mul ecx ; eax = eax * X
add eax, 7 ; eax = eax + Y (Y = 7)
mov ecx, second ; ecx = 上限
sub ecx, first ; ecx = 上限 - 下限
inc ecx ; Z = ecx + 1 (得到了范围)
xor edx, edx ; edx = 0
div ecx ; eax = eax mod Z (余数在edx里面)
add edx, first ; 修正产生的随机数的范围
mov eax, edx ; eax = Rand_Number
ret
iRand endp
然后用以下语句调用:
invoke iRand, 1, 100
这样就产生了一个在 1 和 100 之间的随机数啦。
是不是很简单呢?最后我再给出一个利用本代码的例子,演示如何生成随机数:
;*********************************************************
;程序名称:随机数的产生原理与实现
;作者:罗聪
;日期:2002-11-21
;出处:http://www.LuoCong.com(老罗的缤纷天地)
;注意事项:如欲转载,请保持本程序的完整,并注明:
;转载自“老罗的缤纷天地”(http://www.LuoCong.com)
;*********************************************************
.386
.model flat, stdcall
option casemap:none
include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
include /masm32/include/user32.inc
includelib /masm32/lib/kernel32.lib
includelib /masm32/lib/user32.lib
WndProc proto :DWORD, :DWORD, :DWORD, :DWORD
iRand proto :DWORD, :DWORD
.const
IDC_BUTTON_GENERATE equ 3000
IDC_EDIT_FIRST equ 3001
IDC_EDIT_SECOND equ 3002
.data
szDlgName db "lc_dialog", 0
szCaption db "Rand Number Generator by LC", 0
szText db 255 dup(0)
szTemplate db "(%d ~ %d)随机数:", 13, 10, 13, 10,/
" %d", 13, 10, 13, 10,/
"老罗的缤纷天地", 13, 10,/
"http://www.LuoCong.com", 0
nFirst dd 0
nSecond dd 0
.code
main:
invoke GetModuleHandle, NULL
invoke DialogBoxParam, eax, offset szDlgName, 0, WndProc, 0
invoke ExitProcess, eax
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hEdit: HWND
.if uMsg == WM_CLOSE
invoke EndDialog, hWnd, 0
.elseif uMsg == WM_COMMAND
mov eax, wParam
mov edx, eax
shr edx, 16
movzx eax, ax
.if edx == BN_CLICKED
.if eax == IDCANCEL
invoke EndDialog, hWnd, NULL
.elseif eax == IDC_BUTTON_GENERATE || eax == IDOK
;获得上限:
invoke GetDlgItemInt, hWnd, IDC_EDIT_FIRST, NULL, TRUE
mov nFirst, eax
;获得下限:
invoke GetDlgItemInt, hWnd, IDC_EDIT_SECOND, NULL, TRUE
mov nSecond, eax
;产生随机数:
invoke iRand, nFirst, nSecond
;输出:
invoke wsprintf, addr szText, addr szTemplate, nFirst, nSecond, eax
invoke MessageBox, hWnd, addr szText, addr szCaption, MB_OK or MB_ICONINformATION
.endif
.endif
.else
mov eax, FALSE
ret
.endif
mov eax, TRUE
ret
WndProc endp
;**********************************************************************
; 函数功能:产生范围从 first 到 second 的随机数
; 传入参数:
; first = 下限
; second = 上限
; 返回参数:
; eax = Rand_Number
; 所用公式:
; Rand_Number = (Rand_Seed * X + Y) mod Z
; 补充说明:
; (1)本例中用 GetTickCount 来取得随机数种子,
; 在实际应用中,可用别的方法代替。
; (2)要产生随机数,X和Y其中之一必须是素数,
; 所以 X = 23, Y = 7(可用别的素数代替)
;**********************************************************************
iRand proc uses ecx edx first:DWORD, second:DWORD
invoke GetTickCount ; 取得随机数种子,当然,可用别的方法代替
mov ecx, 23 ; X = ecx = 23
mul ecx ; eax = eax * X
add eax, 7 ; eax = eax + Y (Y = 7)
mov ecx, second ; ecx = 上限
sub ecx, first ; ecx = 上限 - 下限
inc ecx ; Z = ecx + 1 (得到了范围)
xor edx, edx ; edx = 0
div ecx ; eax = eax mod Z (余数在edx里面)
add edx, first ; 修正产生的随机数的范围
mov eax, edx ; eax = Rand_Number
ret
iRand endp
end main
;******************** over ********************
;by LC
它的资源文件:
#include "resource.h"
#define IDC_BUTTON_GENERATE 3000
#define IDC_EDIT_FIRST 3001
#define IDC_EDIT_SECOND 3002
#define IDC_STATIC -1
LC_DIALOG DIALOGEX 10, 10, 210, 60
style DS_SETFONT | DS_CENTER | WS_MINIMIZEBOX | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Rand Number Generator by LC, 2002-11-21"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Please input the range below:", IDC_STATIC, 5, 5, 200, 10
RTEXT "From:", IDC_STATIC, 10, 20, 20, 10
EDITTEXT IDC_EDIT_FIRST, 30, 20, 70, 10, ES_AUTOHSCROLL | NOT WS_BORDER, WS_EX_STATICEDGE
RTEXT "To:", IDC_STATIC, 110, 20, 20, 10
EDITTEXT IDC_EDIT_SECOND, 130, 20, 70, 10, ES_AUTOHSCROLL | NOT WS_BORDER, WS_EX_STATICEDGE
DEFPUSHBUTTON "Generate(&G)", IDC_BUTTON_GENERATE, 70, 40, 50, 13, BS_FLAT | BS_CENTER
END
如果您还有什么疑问,或者发现了我的表述和理解有误,欢迎来信交流。lcother@163.net
老罗于
2002-11-22
随机数的产生原理与实现相关推荐
- 从《羊了个羊》看随机数的生成原理
你的<羊了个羊>第二关通关了吗? 作为一款三消类的休闲小游戏,<羊了个羊>虽然在玩法上并没有多大创新,但却以其相邻关卡间巨大的游戏难度落差成功出圈.讨论度提高的同时,也招致了一 ...
- linux 随机数原理,Linux随机数生成器的原理和缺陷.pdf
第17卷.第10期 计算机技术与发展 vol.17No.10 2007年10月 COMPUTERTECHNOLOGYANDDEVELOPMENT Oct.2007 Linux随机数生成器的原理及缺陷 ...
- linux随机数原理,Linux随机数生成器的原理与缺陷.pdf
第17卷.第10期 计算机技术与发展 vol.17No.10 2007年10月 COMPUTERTECHNOLOGYANDDEVELOPMENT Oct.2007 Linux随机数生成器的原理及缺陷 ...
- 随机数是真是假你说了算???
几乎所有编程语言中都提供了"生成一个随机数"的方法,也就是调用这个方法会生成一个数,我们事先也不知道它生成什么数.比如在.Net中编写下面的代码: Random rand = ne ...
- 【Java】深入理解Java随机数
随机数 根据密码学原理,随机数的随机性检验可以分为三个标准: 统计学伪随机性.统计学伪随机性指的是在给定的随机比特流样本中,1的数量大致等于0的数量,同理,"10""01 ...
- matlab逆变换法产生随机数_信号处理——生成给定分布随机数
作者:桂. 时间:2017-03-12 19:31:55 前言 本文是曲线拟合与分布拟合一文的插曲,进行分布拟合时,碰到一个问题是,如何指定分布的随机数呢?本文主要包括: 1)连续型随机数: 2)离 ...
- /dev/random 和 /dev/urandom 的原理
/dev/random和 /dev/urandom是 Linux 上的字符设备文件,它们是随机数生成器,为系统提供随机数 随机数的重要性 随机数在计算中很重要. TCP/IP 序列号.密码盐和 DNS ...
- 【算法学习】随机化算法 随机数生成器和mt19937
文章目录 1. 伪随机数 2. 模运算 3. 乘同余法随机数生成器 (1) 原理 (2) 程序实现 4. 混合同余法 5. mt19937 1. 伪随机数 Treap.跳跃表和随机快速排序等需要用到随 ...
- Linux随机数发生器
Linux随机数发生器 日期:2017-11-29 01:42:10 星期三 Linux随机数发生器 一.源代码的基本情况 Linux内核版本 涉及文件 功能概述 二.外部访问接口 内核层输出接口 用 ...
最新文章
- 3个著名加密算法(MD5、RSA、DES)的解析
- 交换机基础设置之vtp管理vlan设置
- 谷歌浏览器之如何调试页面js
- Linux笔记-压缩包安装jdk1.7(bash与.cshrc)
- Python的内建属性和内建函数
- 通过样式调整input 中password text默认长度
- 动态路由 RIP的配置方法
- 多线程进行http请求
- C Tricks(十二)—— 获取字符数组的末尾元素
- Android Handler异步通信:深入详解Handler机制源码
- Spring Cloud 各个版本之间的区别
- 计算机教室消防说明,6.7 消防专用电话的设置
- Windows桌面图标消失或桌面路径变更
- revel MySQL_mysql – 如何在Revel Controller中访问Gorm?
- 于众目睽睽之下隐藏图像:深度隐写术
- [技巧]用js生成日志文件、获取ip。
- 音频特征提取方法和工具汇总
- 萍果8html5测试跑分,实力碾压!苹果iPhone8/8 Plus跑分对比
- Carsim与不同版本MATLAB联合仿真设置——个人积累
- 冷启动与热启动的区别
热门文章
- FFT(傅里叶快速变换,详细讲解+推导) 每日一遍,算法再见!
- 卡塔兰数(Catlan)
- 在vue/html中添加单选按钮
- 2019几大主流的前端框架,几款目前最热门的前端框架
- python卸载及python 0x80070643 安装发生严重错误
- 可爱猫+python3+Flask+aiohttp简单搭建微信机器人
- Spring Boot+Vue/前后端分离/高并发/秒杀实战课程之spring Security快速搭建oauth2 内存版身份认证
- https://ac.nowcoder.com/acm/contest/317/D
- serializers.Serializer的用法
- 如何应对“改变现状”的失败