math.randomseed(tostring(os.time()):reverse():sub(1, 6))
即将时间值转换为字符串,然后将字符串倒序,然后取其前六位作为种子。之所以这样做的原因是因为当时间变化很小的时候,产生随机数的序列很相似。所以通过这种方法使得即使时间变化很小,由于reverse操作,时间的高位变成低位,低位变成高位,随机数种子的值变化会很大。
关于这种做法有以下两个问题:
1.当前执行os.time()打印的时间是1560251897,总共十位。认为函数中使用sub(1, 6)这里取前6位的中的6并不是一个固定的值,而且并没有什么意义,直接使用math.randomseed(tostring(os.time()):reverse())就能达到想要的效果。难道有其他我没有想到的原因?
2.这样的做法并不能阻止在同一秒内产生相同的随机数序列,如执行以下代码:
math.randomseed(tostring(os.time()):reverse():sub(1, 6))
print(math.random())
print(math.random())
math.randomseed(tostring(os.time()):reverse():sub(1, 6))
print(math.random())
print(math.random())
输出结果是:
0.49256881466135
0.0046852543018758
0.49256881466135
0.0046852543018758
另一种说法是对计算机的一些操作,如键盘、鼠标操作,会产生一些随机数,这些随机数叫熵。用户可以通过读取/dev/random和/dev/urandom文件来获取这些随机数。只不过读取/dev/random时,如果文件里的熵不足时会阻塞。读取/dev/urandom时,不会阻塞,但不能保证是合适的数据(熵不足时怎么处理未测试)。关于熵的还有其他相关知识,如通过操作鼠标、键盘等可以产生熵,通过cat /proc/sys/kernel/random/entropy_avail操作可以查看有多少熵可以用等。
这样的话,通过读取/dev/urandom设置随机数种子,是一种方法,但觉得这种文件读取操作,效率太低。
另外看留言里有人说通过系统调用,利用芯片电磁噪声来生成随机数。没有搜到是哪个系统调用。
←
06 | OpenResty 中用到的 NGINX 知识