我们都知道,所谓的随机都是伪随机,随机的结果是由随机算法和随机种子决定的。

所以,当我们没有初始化的时候,如果直接使用math.random(),那么出来的值肯定是每次都一样,因为种子等于0。

因此,我们都会在进程启动前,我们先调用一下种子

–随机种子初始化
math.randomseed(tostring(os.time()):reverse():sub(1, 6))

但是,这一切在operensty的多进程里面被打破了,因为随机以后的因子。。各个进程不共享。。

如果,有2个进程,那么意味着,同样的值会出现两遍,比如在游戏里面开宝箱,很容易被玩家抓到规律。

好吧,除非将随机因子放入共享内存,并且自己实现随机算法,不然的话。。math.random是废了!

好了,不需要随机种子的随机方法,我想起了。。/dev/random

以下文档摘自https://zh.wikipedia.org/wiki//dev/random

由于不可抗拒原因,大家可以看看截图

我们只要知道这样的随机方式,不可预测的真随机,来自硬件的因子,并且记得

  • /dev/random是阻塞的
  • /dev/urandom是非阻塞的

那么,对我们而言/dev/urandom是够的,所以。。我还是把代码贴一下就好了

  1. --linbc 20160709
  2. --lua随机函数
  3.  
  4. local MAX_UINT = math.pow(2,32)
  5. local cache_results = {}
  6. local cache_index = 0
  7.  
  8. local table_getn = table.getn
  9.  
  10. --种子不需要初始化了
  11. local function init()
  12. end
  13.  
  14. --从系统随机文件中读取
  15. local function urandom()
  16. --看下缓存里面还有没有
  17. local this_count = table_getn(cache_results) - cache_index
  18. if this_count <= 0 then
  19. --每次读取128个整数,512个字节缓存下来
  20. local COUNT = 1024
  21. local frandom = assert(io.open("/dev/urandom", "rb"))
  22. local s = frandom:read(4 * COUNT)
  23. assert(s:len() == 4 * COUNT)
  24.  
  25. for i=1,COUNT do
  26. --读取4个字节作为一个整数
  27. local v = 0
  28. for c = 1, 4 do
  29. v = 256 * v + s:byte(i*c)
  30. end
  31. cache_results[i] = v
  32. end
  33. io.close(frandom)
  34.  
  35. --重新把
  36. this_count = table_getn(cache_results)
  37. cache_index = 0
  38. end
  39.  
  40. cache_index = cache_index + 1
  41. return cache_results[cache_index]
  42. end
  43.  
  44. local rand = urandom
  45.  
  46. --随机一个0-1之间的浮点数
  47. local function randFloat()
  48. return rand()/(MAX_UINT+1)
  49. end
  50.  
  51. --随机给定范围[a,b]的整数
  52. local function randInt(a, b)
  53. assert(b >= a)
  54. local v = rand()
  55. return a + math.floor((b-a+1)*randFloat())
  56. end
  57.  
  58. return {
  59. init = init,
  60. rand = rand,
  61. urandom = urandom,
  62. randInt = randInt,
  63. randFloat = randFloat
  64. }

由于随机函数是非常频繁的,所以,还是做了一个随机池在那边,先随机一大部分放着

版权声明:本文为linbc原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/linbc/p/10555623.html