有没有人怀疑过 rand()函数得到的随机数并不随机?

2017-05-30 21:20:33 +08:00
 tianxiacangshen
我下载了国外某权威抽奖网站的 300 万期开奖号码的数据,然后自己用 rand()根据开奖规则随机产生了一些号码作为开奖号码,也是 300 万期,分析某个数值比如 9 隔多长时间出现一次的概率,发现有较为明显的差别:

这是彩票网站统计的数据:
90--1--0.0004% (意思是隔 90 期才出现 1 次,概率 0.0004%)
89--0--0%
88--0--0%
87--1--0.0004%
86--2--0.0007%
85--0--0%
84--0--0%
83--0--0%
82--1--0.0004%
81--0--0%
80--0--0%
79--1--0.0004%
78--1--0.0004%
77--1--0.0004%
76--0--0%
75--1--0.0004%
74--1--0.0004%
73--3--0.0011%
72--7--0.0026%
71--2--0.0007%
70--2--0.0007%
69--3--0.0011%
68--11--0.0041%
67--2--0.0007%
66--9--0.0034%
65--8--0.003%
64--11--0.0041%
63--11--0.0041%
62--10--0.0037%
61--4--0.0015%
60--13--0.0049%
59--14--0.0052%
58--14--0.0052%
57--21--0.0078%
56--21--0.0078%
55--18--0.0067%
54--17--0.0064%
53--24--0.009%
52--41--0.0153%
51--42--0.0157%
50--38--0.0142%
49--57--0.0213%
48--76--0.0284%
47--86--0.0321%
46--86--0.0321%
45--100--0.0374%
44--116--0.0433%
43--130--0.0486%
42--144--0.0538%
41--153--0.0572%
40--168--0.0628%
39--227--0.0848%
38--227--0.0848%
37--284--0.1061%
36--347--0.1297%
35--353--0.1319%
34--431--0.1611%
33--491--0.1835%
32--523--0.1954%
31--596--0.2227%
30--704--0.2631%
29--802--0.2997%
28--931--0.3479%
27--962--0.3595%
26--1161--0.4338%
25--1321--0.4936%
24--1536--0.574%
23--1755--0.6558%
22--2009--0.7507%
21--2305--0.8613%
20--2769--1.0347%
19--3096--1.1569%
18--3465--1.2948%
17--3917--1.4637%
16--4508--1.6845%
15--5280--1.973%
14--5922--2.2129%
13--6769--2.5294%
12--7779--2.9068%
11--8770--3.2771%
10--10043--3.7528%
9--11553--4.317%
8--12872--4.8099%
7--15013--5.6099%
6--17385--6.4962%
5--19536--7.3%
4--22339--8.3474%
3--25558--9.5502%
2--29304--10.95%
1--33414--12.4858%

下面是我用 rand 生成的开奖号码中该数值的统计:
90--0--0%
89--0--0%
88--0--0%
87--0--0%
86--0--0%
85--0--0%
84--0--0%
83--0--0%
82--0--0%
81--0--0%
80--0--0%
79--0--0%
78--66--0.0247%(注意这里)
77--0--0%
76--0--0%
75--0--0%
74--0--0%
73--0--0%
72--0--0%
71--0--0%
70--0--0%
69--0--0%
68--0--0%
67--0--0%
66--0--0%
65--0--0%
64--0--0%
63--0--0%
62--0--0%
61--0--0%
60--0--0%
59--65--0.0243%(注意这里)
58--0--0%
57--0--0%
56--0--0%
55--131--0.049%(注意这里)
54--0--0%
53--0--0%
52--0--0%
51--0--0%
50--65--0.0243%(注意这里)
49--66--0.0247%(注意这里)
48--0--0%
47--0--0%
46--0--0%
45--131--0.049%
44--131--0.049%
43--66--0.0247%
42--65--0.0243%
41--261--0.0975%
40--0--0%
39--327--0.1222%
38--130--0.0486%
37--326--0.1218%
36--459--0.1715%
35--524--0.1958%
34--459--0.1715%
33--523--0.1954%
32--721--0.2694%
31--523--0.1954%
30--196--0.0732%
29--1044--0.3901%
28--918--0.343%
27--652--0.2436%
26--1376--0.5142%
25--1572--0.5874%
24--1437--0.537%
23--1568--0.5859%
22--2426--0.9065%
21--2229--0.8329%
20--2620--0.979%
19--3471--1.297%
18--3338--1.2473%
17--3666--1.3699%
16--3795--1.4181%
15--5760--2.1523%
14--5952--2.2241%
13--6550--2.4475%
12--8180--3.0566%
11--9493--3.5472%
10--10683--3.9919%
9--11662--4.3577%
8--13614--5.0871%
7--15721--5.8744%
6--14404--5.3823%
5--19586--7.3187%
4--22190--8.2917%
3--26386--9.8596%
2--28525--10.6589%
1--33564--12.5418%

这么大的差别,足以证明 rand 并不是很靠谱的随机函数吧

纯技术分析,别骂我闲得蛋疼.... /:哭笑
16105 次点击
所在节点    PHP
91 条回复
geelaw
2017-05-30 21:53:37 +08:00
通常 rand 的实现比较随便,这样的结果也不令人吃惊。即使统计上表现很随机,也不代表这个随机就是很“随机”。

如果你希望获取 大量 你看不出来是伪随机 的伪随机数,你需要:

1. 一个随机源;
2. 一个“密码学安全”的随机数生成器。

前者可以用外部熵源产生,后者遍地都是。代价是这些随机数生成比较慢。
blankme
2017-05-30 21:55:42 +08:00
@est 设置同样的 seed
bp0
2017-05-30 22:18:03 +08:00
@tianxiacangshen 如果是真随机自然是不能按概率。
yangff
2017-05-30 22:20:21 +08:00
比如热噪声……

如果你对伪随机数有兴趣可以读一下这本 http://www.ituring.com.cn/book/987
dangyuluo
2017-05-30 22:25:49 +08:00
记得有个网站用放射性元素来做随机数服务
DuckJK
2017-05-30 22:28:03 +08:00
http://wonderkun.cc/index.html/?p=585
http://www.yulegeyu.com/2017/05/13/PHPCMS-MT-RAND-SEED-CRACK%E8%87%B4authkey%E6%B3%84%E9%9C%B2%E3%80%82/

rand()和 mt_rand()都是伪随机,在一定情况下,找到种子就可以预测下一次的数值。
duola
2017-05-30 22:28:10 +08:00
之前听别人说过随机数并不随机的,想不到楼主来验证了。
grimpil
2017-05-30 22:30:57 +08:00
rand()是伪随机,彩票开奖号码绝更不可能是随机的,肯定有人为控制的情况。

如果开奖号码真的是完全由随机函数生成,不管是真随机还是伪随机,反倒好预测了。正是加入了人为控制,所以预测难度大增。

另外,现在的彩票都是当期停售之后才摇奖,想要人为控制才容易了。装模作样弄个电视直播,鬼才信。

这已经不是你能不能预测到的问题了,而是人家想不想让你预测到。
acros
2017-05-30 22:39:27 +08:00
是时候分享一下这个压箱底随机代码了。
geelaw
2017-05-30 22:41:58 +08:00
@grimpil 怎么预测随机数?
spongebobsun
2017-05-30 22:49:27 +08:00
@acros 这个我也有哈哈哈哈
jininij
2017-05-30 22:59:23 +08:00
linux 生成真随机数 直接从 /dev/random 中读。php 可以用 openssl_random_pseudo_bytes,这个函数是用来生成密钥的,随机性应该不错。这些随机数发生器大多使用系统芯片的白噪音,或者使用多线程竞争的不确定性来生成种子。如果你需要更可靠的随机数,可以使用专用的随机数芯片。它使用量子不确定性来产生随机数,可以做到绝对的随机和完美的分布。
不知道如果你盯着这个芯片看,会不会导致量子坍缩。然后每次都生成同一个数。
mingyun
2017-05-30 23:24:09 +08:00
@acros 666
wujunze
2017-05-30 23:31:23 +08:00
本来就是伪随机数 可以试试这个 https://www.random.org/
wenzhoou
2017-05-30 23:33:42 +08:00
实际上你只要对着随机数结果看的时候,就会导致量子坍缩。即使你不看,用脑子想想就足够让量子坍缩。
msg7086
2017-05-30 23:40:30 +08:00
@acros 42 比 4 更好一些。
DevNet
2017-05-30 23:57:51 +08:00
我记得 e 语言的伪随机是取的系统时钟以秒位单位的小数点后几位,然后计算得到一个值
vibbow
2017-05-30 23:58:36 +08:00
电脑有硬件 TPM 芯片的话,Windows 系统会调用 TPM 芯片生成真随机数的
Linux 好像需要手动设置一下

至于 PHP 是不是调用系统函数生成随机数的......
hst001
2017-05-31 00:08:26 +08:00
有多跑两次看看结果如何吗?
seeker
2017-05-31 01:22:36 +08:00
有人怀疑过这个世界上是否存在真随机?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/364780

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX