有没有人怀疑过 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 并不是很靠谱的随机函数吧

纯技术分析,别骂我闲得蛋疼.... /:哭笑
16026 次点击
所在节点    PHP
91 条回复
Tunar
2017-05-31 10:24:59 +08:00
本来就是伪随机,,,
http://www.tuicool.com/articles/IZ3EBvQ
fxxkgw
2017-05-31 10:29:55 +08:00
一层层看完了 学习了学习了
tianxiacangshen
2017-05-31 10:37:50 +08:00
@bk201

分布太异常了,官网开奖的号码可以说是和概率,事实相符合的,而用 rand 生成的,后半部分和官网基本上没差别,但是前半部分,开奖号码基本上都集中在一些号码上面而不是随机分布,这就很不符合事实。

当然这并不绝对,真实的随机分布也可能发生这样的事,但是几乎不可能出现的事出现了,只能认为 rand 函数有问题

就好比抛 1000 次硬币,全都正面朝上的也是有可能的,但是事实上你抛 1000 次会出现 1000 次都朝上吗?
songsong
2017-05-31 10:37:57 +08:00
不是真随机数
Tunar
2017-05-31 10:44:21 +08:00
真随机数生成可与真实物理事件结合,学习了~
sampeng
2017-05-31 10:46:03 +08:00
彩票那是用球摇出来的好伐。。那不是程序生成的。。。。
HGladIator
2017-05-31 10:49:00 +08:00
学习了
BOYPT
2017-05-31 10:49:59 +08:00
研究随机函数的随机规律,一个方式是生成彩虹表,如果有明显的分布规则,很容易一目了然。
rand 简单来说就是读取 /dev/urandom,这也不是 php 的祸,是操作系统的。
exoticknight
2017-05-31 10:51:23 +08:00
没有怀疑过,因为早知道是伪随机了
jybox
2017-05-31 10:53:43 +08:00
@shoaly 是的,在抽奖这种场景中我们要的并不不一定是真随机,而只是无法控制而已,我前一阵写过一个基于去中心化技术的抽奖程序,就是按照这个思路 https://jysperm.me/2017/02/distributed-random-rollup
@zocome 真随机不代表不重复,真随机就是什么情况都是有可能发生的(当然次数越多约接近期望概率),连着重复几个也是有可能的
lrxiao
2017-05-31 10:56:22 +08:00
我记得知乎有科普(如何判断伪随机生成器的质量)
PHP5 的 rand 实现似乎是有问题的..你看知乎那个图
lrxiao
2017-05-31 10:58:05 +08:00
zhengxiaowai
2017-05-31 11:18:17 +08:00
你听过安全随机数么
wsfdljy
2017-05-31 11:19:23 +08:00
@seeker 此贴开始进入哲学环节
cxh116
2017-05-31 11:22:16 +08:00
楼主,这是一条发财的好道路,不信你搜 "老虎机 伪随机". 月入百万不是梦.
bleaker
2017-05-31 11:25:16 +08:00
懒得看书的话,这里有个比较易懂的解释 https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d
Clarencep
2017-05-31 11:37:45 +08:00
据测试,rand()函数的随机程度确实不如 /dev/random:



不过相差的好像并不是特别大吧...

附测试代码: https://gist.github.com/Clarence-pan/ff572272fe3e237df39639b7d6cb7e99
chinawrj
2017-05-31 12:57:59 +08:00
了解一下伪随机和真随机吧。还有随机函数发生器,随机数种子等概念。
q9S
2017-05-31 14:51:53 +08:00
ps -ef | md5sum
BOYPT
2017-05-31 15:00:26 +08:00
看测试还不如看看 php 的 random 实现代码:
https://github.com/php/php-src/blob/master/ext/standard/random.c

随机源都是从操作系统底层提供的,然后 php 做一下边界检测等等,Linux 下随机数来源依然是
fd = open("/dev/urandom", O_RDONLY);

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

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

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

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

© 2021 V2EX