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

纯技术分析,别骂我闲得蛋疼.... /:哭笑
16158 次点击
所在节点    PHP
91 条回复
GtDzx
2017-05-31 15:11:21 +08:00
题主在问统计结果上的差别。和真随机伪随机没关系吧...
伪随机在这种统计上也应该是没差别的。比如你用 rand()掷个筛子得到的结果也应该是每面 1/6 概率啊。
8023
2017-05-31 15:24:01 +08:00
@acros 请问这是什么梗?
Clarencep
2017-05-31 17:41:45 +08:00
@BOYPT random_bytes 是 PHP7 后加的,而 rand()函数的代码在这里: https://github.com/php/php-src/blob/c8aa6f3a9a3d2c114d0c5e0c9fdd0a465dbb54a5/ext/standard/rand.c

最终用的是这样的算法:

/* {{{ php_mt_rand
*/
PHPAPI uint32_t php_mt_rand(void)
{
/* Pull a 32-bit integer from the generator state
Every other access function simply transforms the numbers extracted here */

register uint32_t s1;

if (UNEXPECTED(!BG(mt_rand_is_seeded))) {
php_mt_srand(GENERATE_SEED());
}

if (BG(left) == 0) {
php_mt_reload();
}
--BG(left);

s1 = *BG(next)++;
s1 ^= (s1 >> 11);
s1 ^= (s1 << 7) & 0x9d2c5680U;
s1 ^= (s1 << 15) & 0xefc60000U;
return ( s1 ^ (s1 >> 18) );
}

https://github.com/php/php-src/blob/c8aa6f3a9a3d2c114d0c5e0c9fdd0a465dbb54a5/ext/standard/mt_rand.c#L163~L185
kokdemo
2017-05-31 17:53:53 +08:00
好像真随机都是什么 粒子数据,大气数据什么的
tianxiacangshen
2017-05-31 18:38:57 +08:00
@GtDzx 我之前也是认为没关系才去统计,实际上是有关系的,随机的每一次号码都随机,没有任何规律,而 rand 有一定规律,在一定条件下可以预测到下一次的号码
acros
2017-05-31 19:56:56 +08:00
@8023 https://xkcd.com/
xkcd 的系列漫画
iyaozhen
2017-05-31 21:14:03 +08:00
至少你得用 mt_rand 吧。一般也满足需求
bobylive
2017-05-31 23:14:22 +08:00
計算機生成的本來就是偽隨機數,這不是常識來的麼
MadisonRong
2017-06-01 17:46:52 +08:00
本来就是伪随机,之前还看过一篇文章,只要你掌握算法,可以用随机种子生成出固定的序列
alvinbone88
2017-06-01 18:24:56 +08:00
恰恰相反,这反而说明数字很随机。本福特定律指出,在 b 进制中,以数 n 开头的数出现的概率为 log<sub>b</sub>(n+1)-log<sub>b</sub>(n)
cncqw
2017-06-05 09:09:44 +08:00
@zocome 几百万条数据,递归查询一下,这效率得多慢

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

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

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

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

© 2021 V2EX