【有彩蛋】关于“真伪随机数”的思考,及原创的一个Visual Basic的小程序

众所周知,绝大多数编程语言或者脚本语言乃至shell,都有产生随机数功能。

根据随机数的生成原理,我们把电脑随机数分为两类:“真”随机数和伪随机数。

  • 要生成一个“真”随机数,电脑会检测电脑外部发生的某种物理现象。比如说,电脑可以测量某个原子的放射性衰变。根据量子理论,原子衰变是随机而不可测的,所以这就是宇宙中的“纯粹”随机性。

举个例子,你的电脑监测到你某天上午8点以后敲击键盘的精确时间是0.87956869秒,有足够的这些特定长数字你就能得到一个熵源,也就可以生成“真”随机数。Linux中的/dev/随机设备生成随机数,“阻拦”访问直到熵积累量足够才返回一个真随机数。

  • 伪随机数这个概念是相对于“真”随机数而言。电脑通过发送种子数值,运用算法产生某个看起来像随机数的数字,但是实际上这个数字是可以预测的。因为电脑没有从环境中收集到任何随机信息。

虽然是伪随机数,但是并不是所有领域都不需要伪随机数。比如,如果你在玩电子游戏,那么游戏过程中是靠伪随机数还是真随机数并不重要。另一方面,如果你的应用正在加密,情况就不同了,因为你不希望攻击者能够猜到你的随机数。

下面就是我关注的重点。

让计算机帮你随机做个选择,“0”或者“1”,也可以说是A或者B,这真的是随机的吗?

我把目光放在VB(Visual Basic)的Rnd()函数。

首先放出小程序的界面:

程序的界面

即可以通过设定随机数产生次数(0或1的随机数),自动得出各个选项的概率,来验证随机数是否存在规律。若为“真随机数”,各个概率在总数的数值为多少时接近于相等(理想状况)?

程序源码

 下面还是直接给出源代码好了。这个工具,开源最好了。

Private Sub Command1_Click()
List1.Clear
List2.Clear
Dim cs As Long
cs = Val(Text1.Text)
Dim bl(1000000) As Long
For i = 1 To cs
bl(i) = Rnd
List1.AddItem bl(i)
If bl(i) = 0 Then l = l + 1
If bl(i) = 1 Then y = y + 1
Next i
Text2.Text = Str(l)
Text3.Text = Str(y)
List2.AddItem Str(l / cs)
List2.AddItem Str(y / cs)
End Sub

源代码中,计数器“l”和“y”分别承担“0”和“1”的统计任务,两个list列表显示具体概率和依次数值。那么现在,程序设计的思想大家都应该理解了:整个程序只需给出具体生成次数,就可以默默等待计算机快速“抛硬币”再告知你生成结果了。

下面我放出具体测试的一些结果。点击“开始生成”按钮,然后一直按“回车Enter”键,那个效果不错。

测试结果

当总测试次数超过1万数量级。需等待5-10秒钟的生成过程。需要耐心等待。从下面结果可以看出。数值变大后,双方概率明显更接近与50%。

程序生成结果

当给定生成次数超过10万数量级(超过十二万),需要近1分钟的时间进行运算,中途可能出现未响应状况。当然这因计算机配置的不同而存在差异。

运行结果

所以如果需要100万以上数量级的数据,可以考虑通过云计算能力进行生成。图中可以看出程序对CPU要求较高。

任务占用情况

我当然不会把这个程序放在网站的云服务器上进行计算。无论怎样,我都不会在上万用户访问的公网服务器上进行这个需要占用大量CPU资源的计算任务。

如果有人和我一样好奇,可以贡献一下你的力量。把这个程序放在你个人使用的非公用(云)服务器上运行,甚至可以考虑上千万数量级的运算结果,当然这需要修改我提供的上述源码的“bl”数组范围。

最后放一个彩蛋。等了那么长时间(真的很长),结果应该是我定义的bl数组范围不够。我无奈了。QAQ

 彩蛋情况

最后的最后,奉上这个我原创的程序,大家可以试试,只要不把这个程序当做祸害CPU的助手。。。

下载按钮     随机运算程序

《【有彩蛋】关于“真伪随机数”的思考,及原创的一个Visual Basic的小程序》有96,110个想法

发表评论