1
nvkou 2017-05-30 21:24:43 +08:00
只能说明这个随机不等同于那个随机。不严谨的随机数生成都是梅森螺旋做出来的吧。
|
2
metowolf 2017-05-30 21:25:54 +08:00
计算机中实现的随机本身就是伪随机,是通过多项式生成的
|
3
bp0 2017-05-30 21:26:58 +08:00
rand 的一直都是伪随机,而且不是按概率分布的。
|
4
tianxiacangshen OP |
5
tianxiacangshen OP @bp0 既然随机,就不能按概率吧
|
6
Kilerd 2017-05-30 21:29:24 +08:00 via iPhone 1
@tianxiacangshen 如果有完全凭软件的方法能写出真随机的话,快去写论文,估计,不,我保证下届图灵奖是你的了
|
7
ipconfiger 2017-05-30 21:29:49 +08:00
本来就是伪随机啊
|
8
tianxiacangshen OP @Kilerd 哈哈,换个说法,如何用程序实现像权威彩票网站那样的随机号码?
|
9
ovear 2017-05-30 21:34:49 +08:00 2
|
10
blankme 2017-05-30 21:35:19 +08:00 via Android
说“ rand()不好”时,首先你要说明你用的 rand 用的是哪个库里的函数,用的是什么算法。
现在用的比较多的是 Mersenne twister,随机数质量好,生成速度也快。 追求“真随机”,那就做真实的物理上的实验,比如做量子实验,实验结果就是随机序列。不过效率比较低而已。 |
11
jellybool 2017-05-30 21:35:20 +08:00 via iPhone
@tianxiacangshen 你把地球当时的时刻的磁场变化,潮汐变化计算在内就差不多了
|
12
EmdeBoas 2017-05-30 21:36:52 +08:00
随机也是有分布的,numpy 里面有各种各样分布的随机函数,按需求去用咯
|
13
metowolf 2017-05-30 21:39:45 +08:00 2
https://www.random.org/
可以考虑调用它的 API,宣传说是真随机 |
14
limhiaoing 2017-05-30 21:41:22 +08:00
楼主方便分享下代码吗?
虽然知道是 rand 是伪随机, 但结果中的 78--66--0.0247% 看起来还是很意外的。 |
15
tianxiacangshen OP |
16
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).
|
17
shoaly 2017-05-30 21:46:01 +08:00 3
@tianxiacangshen 其实如果是彩票这种案例的话, 不用那么强调 "真随机", 因为官方再怎么说真随机, 彩民都不一定相信.
所以不如公开一个算法, 做到 事先无法预测, 事后可以检验即可, 比如 : 1 前一天股票的收盘指数 + v2 上 10:00 的在线人数 + 日期 等等 作为基础, 做一个加减乘除开方之类, 然后取小数点后第 6 位作为 幸运数字. |
18
zocome 2017-05-30 21:47:35 +08:00
rand()和 mt_rand()生成的都不是真随机数,都有一定概率重复,就算加上毫秒什么的还是有几率重复
之前生成随机订单数据,总共跑了大概 300W 条数据,大概每 10W 就有一次订单号重复的,还好我的情况是写数据库,递归查询一下就好了 |
20
est 2017-05-30 21:51:55 +08:00
面试题:如何在两个机器上调用 rand() 得到相同的值。
|
21
geelaw 2017-05-30 21:53:37 +08:00
通常 rand 的实现比较随便,这样的结果也不令人吃惊。即使统计上表现很随机,也不代表这个随机就是很“随机”。
如果你希望获取 大量 你看不出来是伪随机 的伪随机数,你需要: 1. 一个随机源; 2. 一个“密码学安全”的随机数生成器。 前者可以用外部熵源产生,后者遍地都是。代价是这些随机数生成比较慢。 |
23
bp0 2017-05-30 22:18:03 +08:00
@tianxiacangshen 如果是真随机自然是不能按概率。
|
24
yangff 2017-05-30 22:20:21 +08:00 1
|
25
dangyuluo 2017-05-30 22:25:49 +08:00
记得有个网站用放射性元素来做随机数服务
|
26
DuckJK 2017-05-30 22:28:03 +08:00 1
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()都是伪随机,在一定情况下,找到种子就可以预测下一次的数值。 |
27
duola 2017-05-30 22:28:10 +08:00
之前听别人说过随机数并不随机的,想不到楼主来验证了。
|
28
grimpil 2017-05-30 22:30:57 +08:00
rand()是伪随机,彩票开奖号码绝更不可能是随机的,肯定有人为控制的情况。
如果开奖号码真的是完全由随机函数生成,不管是真随机还是伪随机,反倒好预测了。正是加入了人为控制,所以预测难度大增。 另外,现在的彩票都是当期停售之后才摇奖,想要人为控制才容易了。装模作样弄个电视直播,鬼才信。 这已经不是你能不能预测到的问题了,而是人家想不想让你预测到。 |
29
acros 2017-05-30 22:39:27 +08:00 10
是时候分享一下这个压箱底随机代码了。
|
31
spongebobsun 2017-05-30 22:49:27 +08:00 via iPhone
@acros 这个我也有哈哈哈哈
|
32
jininij 2017-05-30 22:59:23 +08:00 via Android
linux 生成真随机数 直接从 /dev/random 中读。php 可以用 openssl_random_pseudo_bytes,这个函数是用来生成密钥的,随机性应该不错。这些随机数发生器大多使用系统芯片的白噪音,或者使用多线程竞争的不确定性来生成种子。如果你需要更可靠的随机数,可以使用专用的随机数芯片。它使用量子不确定性来产生随机数,可以做到绝对的随机和完美的分布。
不知道如果你盯着这个芯片看,会不会导致量子坍缩。然后每次都生成同一个数。 |
34
wujunze 2017-05-30 23:31:23 +08:00
本来就是伪随机数 可以试试这个 https://www.random.org/
|
35
wenzhoou 2017-05-30 23:33:42 +08:00 via iPhone
实际上你只要对着随机数结果看的时候,就会导致量子坍缩。即使你不看,用脑子想想就足够让量子坍缩。
|
37
DevNet 2017-05-30 23:57:51 +08:00
我记得 e 语言的伪随机是取的系统时钟以秒位单位的小数点后几位,然后计算得到一个值
|
38
vibbow 2017-05-30 23:58:36 +08:00
电脑有硬件 TPM 芯片的话,Windows 系统会调用 TPM 芯片生成真随机数的
Linux 好像需要手动设置一下 至于 PHP 是不是调用系统函数生成随机数的...... |
39
hst001 2017-05-31 00:08:26 +08:00
有多跑两次看看结果如何吗?
|
40
seeker 2017-05-31 01:22:36 +08:00
有人怀疑过这个世界上是否存在真随机?
|
41
doctorlai 2017-05-31 01:55:11 +08:00
|
42
ryd994 2017-05-31 03:22:16 +08:00 via Android 1
@vibbow Linux 默认 /dev/random 就是从物理事件获得的随机熵 比如寻道时间,键盘鼠标事件
对于不要求完全随机的,还有 /dev/urandom,就是以 random 为种子,如果熵池不够的话就会用软件补齐 Intel 近年的 CPU 带热噪声随机数生成器 当你 Linux 还讨论过要不要用 现在是也一起混入熵池,反正全部是 xor 进去的 |
45
phrack 2017-05-31 07:28:32 +08:00 via Android 1
知识不够 v2 来补
让你不好好学习基础 |
46
tianxiacangshen OP @phrack 惭愧惭愧
|
47
andyhuzhill 2017-05-31 08:48:01 +08:00
@grimpil 我也想知道 随机数怎么能够预测?
|
48
Halry 2017-05-31 08:56:24 +08:00 via Android
部分可以调用芯片内的 trng,做到了比较真的随机数
intel 好像从 haswell 开始芯片里面就内置了 secure key 生成器,出来的随机数还算比较真吧 |
49
jeffersonpig 2017-05-31 08:57:38 +08:00
@ynyounuo 但它就是宇宙的终极答案
|
50
jeffersonpig 2017-05-31 09:00:35 +08:00
@yangff 2333 买过《具体数学》结果收到货了才发现是封面是中文内容是英文原版,从此供起在书架上再也没碰过
|
51
breeswish 2017-05-31 09:06:39 +08:00
rand() 当然不随机,不仅有线性性而且是可预测的。
好几次 CTF 都有过需要预测 PHP 随机数的题了。 |
52
breeswish 2017-05-31 09:08:11 +08:00
附链接,自己以前一个预测随机数的方案: https://breeswish.org/blog/2016/03/16/0ctf-2016-quals-rand-2-writeup/
|
53
coolypf 2017-05-31 09:16:25 +08:00
C++ 可以用 std::mt19937 和 std::mt19937_64 生成高质量伪随机数。
参见 http://www.cplusplus.com/reference/random/ |
54
blankme 2017-05-31 09:20:19 +08:00 via Android
@breeswish 伪随机的可预测性不影响随机性,这两个是不矛盾的。
只要随机序列满足一定的测试要求,就可以用于模拟计算,即使这个序列是已知的。 随机数产生器的很多应用场景并不要求“未知”,而是要求满足均匀分布的统计特性。 |
55
reus 2017-05-31 09:43:26 +08:00
linux 可以读 /dev/urandom 或者 /dev/random,这个是比较随机的,因为数据源是各种设备驱动的事件,例如你键盘的输入可以看作是随机的吧,鼠标的移动也是,硬盘的读写也会产生各种事件,还有网络那些。比纯算法产生的好得多。windows 也有类似的设施。
|
57
neighbads 2017-05-31 09:49:29 +08:00
热噪声。硬件产生的,国密局有随机数检测要求,,
|
58
caniuse 2017-05-31 09:51:15 +08:00
random_bytes
|
59
bk201 2017-05-31 09:59:03 +08:00 via iPhone
我就想知道你怎么知道这个不是随机数?你告诉我看分布?
|
60
Clarencep 2017-05-31 10:10:37 +08:00
一般各种语言的基本库里面的 rand()函数不都配对一个 srand()的设置随机数种子的函数吗? 相同的种子后面产生的随机数都是一样的, 那自然随机性不是那么的好。
linux 下的 /dev/random 是一个不错的选择。但是使用 linux 的 /dev/random 的时候要注意,很有可能会被阻塞住的: 参考 wikipedia: > 发生器有一个容纳噪声数据的熵池,在读取时,/dev/random 设备会返回小于熵池噪声总数的随机字节。/dev/random 可生成高随机性的公钥或一次性密码本。若熵池空了,对 /dev/random 的读操作将会被阻塞,直到收集到了足够的环境噪声为止[3]。这样的设计使得 /dev/random 是真正的随机数发生器,提供了最大可能的随机数据熵,建议在需要生成高强度的密钥时使用。 > /dev/random 的一个副本是 /dev/urandom (“ unblocked ”,非阻塞的随机数发生器[4]),它会重复使用熵池中的数据以产生伪随机数据。这表示对 /dev/urandom 的读取操作不会产生阻塞,但其输出的熵可能小于 /dev/random 的。它可以作为生成较低强度密码的伪随机数生成器,不建议用于生成高强度长期密码。 |
61
Tunar 2017-05-31 10:24:59 +08:00 via Android
本来就是伪随机,,,
http://www.tuicool.com/articles/IZ3EBvQ |
62
fxxkgw 2017-05-31 10:29:55 +08:00
一层层看完了 学习了学习了
|
63
tianxiacangshen OP @bk201
分布太异常了,官网开奖的号码可以说是和概率,事实相符合的,而用 rand 生成的,后半部分和官网基本上没差别,但是前半部分,开奖号码基本上都集中在一些号码上面而不是随机分布,这就很不符合事实。 当然这并不绝对,真实的随机分布也可能发生这样的事,但是几乎不可能出现的事出现了,只能认为 rand 函数有问题 就好比抛 1000 次硬币,全都正面朝上的也是有可能的,但是事实上你抛 1000 次会出现 1000 次都朝上吗? |
64
songsong 2017-05-31 10:37:57 +08:00
不是真随机数
|
65
Tunar 2017-05-31 10:44:21 +08:00 via Android
真随机数生成可与真实物理事件结合,学习了~
|
66
sampeng 2017-05-31 10:46:03 +08:00
彩票那是用球摇出来的好伐。。那不是程序生成的。。。。
|
67
HGladIator 2017-05-31 10:49:00 +08:00
学习了
|
68
BOYPT 2017-05-31 10:49:59 +08:00
研究随机函数的随机规律,一个方式是生成彩虹表,如果有明显的分布规则,很容易一目了然。
rand 简单来说就是读取 /dev/urandom,这也不是 php 的祸,是操作系统的。 |
69
exoticknight 2017-05-31 10:51:23 +08:00
没有怀疑过,因为早知道是伪随机了
|
70
jybox 2017-05-31 10:53:43 +08:00
@shoaly 是的,在抽奖这种场景中我们要的并不不一定是真随机,而只是无法控制而已,我前一阵写过一个基于去中心化技术的抽奖程序,就是按照这个思路 https://jysperm.me/2017/02/distributed-random-rollup
@zocome 真随机不代表不重复,真随机就是什么情况都是有可能发生的(当然次数越多约接近期望概率),连着重复几个也是有可能的 |
71
lrxiao 2017-05-31 10:56:22 +08:00
我记得知乎有科普(如何判断伪随机生成器的质量)
PHP5 的 rand 实现似乎是有问题的..你看知乎那个图 |
72
lrxiao 2017-05-31 10:58:05 +08:00
https://www.zhihu.com/question/20222653
看余天升的答案... |
73
zhengxiaowai 2017-05-31 11:18:17 +08:00
你听过安全随机数么
|
75
cxh116 2017-05-31 11:22:16 +08:00
楼主,这是一条发财的好道路,不信你搜 "老虎机 伪随机". 月入百万不是梦.
|
76
bleaker 2017-05-31 11:25:16 +08:00
懒得看书的话,这里有个比较易懂的解释 https://medium.com/@betable/tifu-by-using-math-random-f1c308c4fd9d
|
77
Clarencep 2017-05-31 11:37:45 +08:00
据测试,rand()函数的随机程度确实不如 /dev/random:
不过相差的好像并不是特别大吧... 附测试代码: https://gist.github.com/Clarence-pan/ff572272fe3e237df39639b7d6cb7e99 |
78
chinawrj 2017-05-31 12:57:59 +08:00
了解一下伪随机和真随机吧。还有随机函数发生器,随机数种子等概念。
|
79
q9S 2017-05-31 14:51:53 +08:00
ps -ef | md5sum
|
80
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); |
81
GtDzx 2017-05-31 15:11:21 +08:00
题主在问统计结果上的差别。和真随机伪随机没关系吧...
伪随机在这种统计上也应该是没差别的。比如你用 rand()掷个筛子得到的结果也应该是每面 1/6 概率啊。 |
83
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 |
84
kokdemo 2017-05-31 17:53:53 +08:00
好像真随机都是什么 粒子数据,大气数据什么的
|
85
tianxiacangshen OP @GtDzx 我之前也是认为没关系才去统计,实际上是有关系的,随机的每一次号码都随机,没有任何规律,而 rand 有一定规律,在一定条件下可以预测到下一次的号码
|
86
acros 2017-05-31 19:56:56 +08:00 1
|
87
iyaozhen 2017-05-31 21:14:03 +08:00
至少你得用 mt_rand 吧。一般也满足需求
|
88
bobylive 2017-05-31 23:14:22 +08:00 via Android
計算機生成的本來就是偽隨機數,這不是常識來的麼
|
89
MadisonRong 2017-06-01 17:46:52 +08:00
本来就是伪随机,之前还看过一篇文章,只要你掌握算法,可以用随机种子生成出固定的序列
|
90
alvinbone88 2017-06-01 18:24:56 +08:00
恰恰相反,这反而说明数字很随机。本福特定律指出,在 b 进制中,以数 n 开头的数出现的概率为 log<sub>b</sub>(n+1)-log<sub>b</sub>(n)
|