美文网首页
抽奖业务中随机数改进

抽奖业务中随机数改进

作者: Teech | 来源:发表于2020-02-17 18:57 被阅读0次

    在很多业务中,都会使用随机数,尤其很多抽奖类业务,总希望产生“质量”较高的随机序列,大部分都是使用启动时间戳作为一个随机数种子,使用C库自带的伪随机算法。

    • 随机算法
      很多自带的随机算法本身就是一个线性同余算法,有加法和乘法所以效率很高。
      线性同余的状态转移方程为f(n+1) = (a * f(n) + c) % m,其中最初设置的种子为f(0)。其实a,c,m常数直接影响随机数的质量。
      但是随机数要求除了要求得到统计上的均匀分布外,还有其他要求,比如不能根据已经存在的序列推测将来的序列。但是目前的伪随机算法都有一定的周期性,看线性同余的代码就可以直觉上感觉到有周期性,因为有个取余操作。

      下面上2张图来对比下不同的随机算法的质量。 1.jpg
    2.jpg

    这个可以很直观的感觉到图2中的随机质量很差,周期很明显。所以glibc或者一些语言自带的随机算法不能满足对随机数要求较高的场景,尤其是抽奖类业务。所以推荐一些质量更高的伪随机算法,常见的比如梅森旋转算法,WELL算法。

    • 伪随机种子
      大部分业务在在伪随机算法开始通过当前的时间戳来设置种子,这种做法及其容易被推测。之前我看过杭州小汽车摇号的视频,伪随机的种子都是通过气球去摇号码的来保证种子的真随机性。如何在代码中获取真随机数呢,intel的cpu提供指令RDSEED来获取,值是由芯片上的熵池初始化的,这个就提供了一个和摇号类似的真随机数种子了,但是为什么不是每个随机数都是通过真随机来获取呢,因为通过获取硬件的熵池的数据办法效率很低,一般只用作初始化伪随机算法来使用。以前看过一些代码在整个随机过程中,随便多次设置种子(为了防止别人推测种子)这个是个不对的做法,因为多次设置种子后可能导致整个序列都不会在统计上符合均匀分布了,所以种子只能设置一次。

    通过对伪随机算法的改进以及随机种子的设置改善,可以大大提高随机数的安全性。

    相关文章

      网友评论

          本文标题:抽奖业务中随机数改进

          本文链接:https://www.haomeiwen.com/subject/nlbffhtx.html