PRNG(伪随机数生成器)






1.75/5 (9投票s)
2001年6月13日
5分钟阅读

162434

1260
用于在 VB/VBScript/ASP 页面中生成随机数的 ActiveX 控件
引言
如果您尝试在程序中使用 Randomize
和 Rnd
,您就会明白我的意思。几率令人难以置信,但您仍然会面对那些相同的、反复出现的“随机”数字。
这是因为像 VB 和其他一些语言一样,它们有一个内置的“随机数表”。VB 的(因此 VBScript 的)是一个由 16,777,215 个随机数组成的表(这恰巧是那些神奇数字之一)。调用 randomize()
会将您定位在表中的某个位置(这通常基于一天中的时间)。调用 rnd()
会返回该值并将其前进到列表中的下一个值。如果您不调用 randomize
再次运行程序,rnd()
每次都会给出相同的值。
问题:获取好的随机数
我个人厌倦了在我的 VB 和 ASP 应用程序中处理由 Randomize
和 Rnd
引起的问题,正如“ necessity is the mother of all inventions”(需求是发明之母),我创建了我自己的 PRNG(伪随机数生成器)。
最好的随机数生成器是基于硬件的。我是一个软件开发者,所以我选择了“模仿随机数生成的算法”,或者换句话说,伪随机数生成器 (PRNG)。
我的目标是构建一个 PRNG,它
- 更易于使用
- 在使用
Randomize
和Rnd
方法时,避免所有重复的“随机”数字, - (完全)不使用或依赖
Randomize
和Rnd
, - 不依赖内部随机数表,
- 产生可接受的随机性(参见下面的测试结果),并且
- 让我安心。
存在的问题
问题 1:种子对于获得好的随机数至关重要,并且很难找到好的种子。典型的种子,如当前时间、自重启以来的时钟滴答数、进程 ID 或用户输入,只能产生有限数量的随机位。
问题 2:某些协议可能会“泄露” PRNG 状态的一些细节。鉴于 PRNG 的确定性,这可能会危及安全,除非进行适当的重新播种。换句话说:其他人可以找出您使用的随机数。
问题 3:当您使用最复杂的算法生成随机数时,事情看起来可能很好,也可能看起来是随机的,但它们真的是吗??
随机数的重要性
随机数对于使用加密机制至关重要。随机数的主要用途是密钥生成和确保消息的唯一性,这可以防止各种重放攻击(由于许多随机数不像它们看起来那样随机,找出密钥的可能性比您认为的要大得多)。身份验证机制可能使用挑战或随机数(一个随机数)来防止重放攻击。
保密机制使用会话密钥(从随机数派生)来在安全交换期间保护数据。数字签名机制需要大的私钥——通常这些密钥的生成从大的随机数(例如,候选素数)开始。
用法
确保您已注册 PRNGMIT.dll 文件。
Set RandomObj = Server.CreateObject("PRNGMIT.prng")
If Err.Number = -2147221005 Or Err.Number = -2147024770 Then
'=== QDNS.dll is not properly installed ================
Response.Write "<font color=red>ActiveX Dll not installed!" & _
" Please copy PRNGMIT.dll to your "
Response.Write "permanent Directory and run ""regsvr32 PRNGMIT.dll"" and " & _
"reboot</font><BR>"
Else
'=======================================================================
'=== Purpose: Generate a Random Number within the given limit
'=== Note: RND expects LowLimit and HighLimit to be of type LONG.
'=== In VBScript everything is a Variant, PRNGMIT is
'=== strongly typed, so
'=== ALWAYS Convert -CLng()- your Values in your ASP Pages.
'========================================================================
Dim LowLimit
Dim HighLimit
LowLimit = 0
HighLimit = 10
Response.Write "Random number between 000 and 010: <B>"
Response.Write RandomObj.Rnd(Clng(LowLimit), _
Clng(HighLimit)) & "</B><BR>"
Response.Write "Random number between 000 and 100: <B>"
Response.Write RandomObj.Rnd(Clng(0), Clng(100)) & "</B><BR>"
Response.Write "Random number between -314 and 786: <B>"
Response.Write RandomObj.Rnd(Clng(-314), Clng(786)) & "</B><BR>"
End If
随机数的统计测试集
无论 PRNG(或您的方法)有多复杂,它本质上仍然是确定性的(……生活充满了模式)。理论上,随机数序列将在(很长)一段时间后循环。检查您使用的方法有多好至关重要。要进行检查,有一套测试。
有关随机数生成器的统计测试集,请参阅 美国国家标准与技术研究院网站。
ENT 伪随机数序列测试程序
请参阅:http://www.fourmilab.ch/random/。
使用此 ENT 测试程序测量我们的 MEELIX PRNG 的随机性,得到了以下结果
熵 = 每字节 7.999403 位。
最佳压缩会将此 11468800 字节文件的尺寸减少 0%。
11468800 个样本的卡方分布为 9483.75,随机情况下,该值将有 0.01% 的概率超过此值。
数据字节的算术平均值为 127.4783(127.5 = 随机)。蒙特卡罗 Pi 值约为 3.141356425(误差 0.01%)。串行相关系数为 0.000090(完全不相关 = 0.0)。
DIEHARD 测试套件
请参阅:http://stat.fsu.edu/~geo/diehard.html。
使用此 DIEHARD 测试套件测量我们的 MEELIX PRNG 的随机性,得到了 以下结果。
快速粗略测试
此测试基于取许多数字的平均值。如果没有偏差,平均值应为 0.5000....等。由于舍入问题,您永远无法获得完美的 0.500000000000000。
下面显示了使用我们的 MEELIX PRNG 运行 25,000、40,000 和 100,000 个随机数的结果
25,000: 0.500025832288101
40,000: 0.499552333479141
100,000: 0.500056488310338
Min: 0.000007182771611 (this is the smallest number from our run)
Max: 0.999989915832831 (this is the largest number from our run)
保证:无
我对我 MEELIX PRNG 没有任何保证,也不保证它生成好的随机数,也不保证源代码按预期工作(无论那是什么)。
简而言之:您可以免费使用和分发此 ActiveX DLL/代码,但您不能收费或将其作为自己的作品。此声明应予保留。所有软件/代码均在“不含任何担保”的情况下提供,无论是明示的还是暗示的。如果您在此代码中发现任何错误,请通知作者。此代码按“原样”提供——如果它不起作用,我们不承担任何责任,也不提供支持(嘿,它是免费的)。
© 版权所有 2001 Meelix Information Technology,保留所有权利。