有没有人怀疑过 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 条回复
nvkou
2017-05-30 21:24:43 +08:00
只能说明这个随机不等同于那个随机。不严谨的随机数生成都是梅森螺旋做出来的吧。
metowolf
2017-05-30 21:25:54 +08:00
计算机中实现的随机本身就是伪随机,是通过多项式生成的
bp0
2017-05-30 21:26:58 +08:00
rand 的一直都是伪随机,而且不是按概率分布的。
tianxiacangshen
2017-05-30 21:27:38 +08:00
@metowolf
@nvkou
对,那如果要产生真正客观的随机数该用什么办法?
tianxiacangshen
2017-05-30 21:28:22 +08:00
@bp0 既然随机,就不能按概率吧
Kilerd
2017-05-30 21:29:24 +08:00
@tianxiacangshen 如果有完全凭软件的方法能写出真随机的话,快去写论文,估计,不,我保证下届图灵奖是你的了
ipconfiger
2017-05-30 21:29:49 +08:00
本来就是伪随机啊
tianxiacangshen
2017-05-30 21:31:42 +08:00
@Kilerd 哈哈,换个说法,如何用程序实现像权威彩票网站那样的随机号码?
ovear
2017-05-30 21:34:49 +08:00
@tianxiacangshen RDRAND 指令集
或者第三方 API https://www.random.org/
blankme
2017-05-30 21:35:19 +08:00
说“ rand()不好”时,首先你要说明你用的 rand 用的是哪个库里的函数,用的是什么算法。

现在用的比较多的是 Mersenne twister,随机数质量好,生成速度也快。

追求“真随机”,那就做真实的物理上的实验,比如做量子实验,实验结果就是随机序列。不过效率比较低而已。
jellybool
2017-05-30 21:35:20 +08:00
@tianxiacangshen 你把地球当时的时刻的磁场变化,潮汐变化计算在内就差不多了
EmdeBoas
2017-05-30 21:36:52 +08:00
随机也是有分布的,numpy 里面有各种各样分布的随机函数,按需求去用咯
metowolf
2017-05-30 21:39:45 +08:00
https://www.random.org/
可以考虑调用它的 API,宣传说是真随机
limhiaoing
2017-05-30 21:41:22 +08:00
楼主方便分享下代码吗?
虽然知道是 rand 是伪随机,
但结果中的 78--66--0.0247% 看起来还是很意外的。
tianxiacangshen
2017-05-30 21:42:00 +08:00
@metowolf
@ovear 这个站是有注意到,宣传说真随机,API 每天能调用 1000 次
limhiaoing
2017-05-30 21:45:13 +08:00
There are no guarantees as to the quality of the random sequence produced. In the past, some implementations of rand() have had serious shortcomings in the randomness, distribution and period of the sequence produced (in one well-known example, the low-order bit simply alternated between 1 and 0 between calls).
shoaly
2017-05-30 21:46:01 +08:00
@tianxiacangshen 其实如果是彩票这种案例的话, 不用那么强调 "真随机", 因为官方再怎么说真随机, 彩民都不一定相信.
所以不如公开一个算法, 做到 事先无法预测, 事后可以检验即可, 比如 :
1 前一天股票的收盘指数 + v2 上 10:00 的在线人数 + 日期 等等 作为基础, 做一个加减乘除开方之类, 然后取小数点后第 6 位作为 幸运数字.
zocome
2017-05-30 21:47:35 +08:00
rand()和 mt_rand()生成的都不是真随机数,都有一定概率重复,就算加上毫秒什么的还是有几率重复

之前生成随机订单数据,总共跑了大概 300W 条数据,大概每 10W 就有一次订单号重复的,还好我的情况是写数据库,递归查询一下就好了
blankme
2017-05-30 21:48:56 +08:00
@EmdeBoas 实际上所有分布都是由(0, 1)区间均匀分布抽样得到的
est
2017-05-30 21:51:55 +08:00
面试题:如何在两个机器上调用 rand() 得到相同的值。

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

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

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

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

© 2021 V2EX