随机数产生原理

本文深入探讨了随机数生成的基本原理,介绍了一种简单的伪随机数生成算法及其应用,包括汇编代码实现和参数选择策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文为转载,地址:http://www.luocong.com/articles/show_article.asp?Article_ID=24,版权问题,马上删除~

随机数的产生在病毒中占有十分重要的地位,尤其是在变形引擎中,没有它就不成事了……因此,今天就让我们来探讨一下如何产生一个随机数。

首先值得说明的是,要产生一个随机数,方法有很多种,例如混沌和分形理论(原理比较复杂,但是公式却异常简单,将来有空的话我会介绍一下)……但是这些方法的缺点是计算难度大,需要花费的时间多,有没有一种实现起来比较简单的方法呢?

答案是肯定的。我们先来看一条数学公式:

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 之间的随机数啦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值