2020-08-12 | 随笔杂记 | UNLOCK | 更新时间:2020-8-12 11:27

关于前端的伪随机问题

在很多时候,前端实现随机数据,都是简单的通过 Math.random() 加工一下来获取想要的随机功能,但是 Math.random() 函数只获取 0 - 1 的 浮点型数据。 这里的区间是 [0,1)也就是你取不到 1 。实现随机数的时候就会需要考虑这个问题。ECMAScript 也未规定厂商用什么算法来实现 Math.random 函数

parseInt(Math.random()*10)+1 // 1 - 10 的随机数,不包括0

Math.floor(Math.random()*(max-min+1)+min) // min - max 的随机数 

然后我们又产生了新的需求,在给定一个确定的初始条件,每次可以生成同样的随机序列,这就是伪随机数生成器

1949 年,数学家 D.H.Lehmer 利用线性同余生成器(LCG)实现了这一思路。下面给出的是基于 Lehmer 的方法所实现的一种朴素 PRNG,叫做中央随机数生成器,使用 JavaScript 在 1995 年写的。

// The Central Randomizer 1.3 (C) 1997 by Paul Houle (paul@honeylocust.com)
// See:  http://www.honeylocust.com/javascript/randomizer.html
rnd.today=new Date();
rnd.seed=rnd.today.getTime();
function rnd() {
  rnd.seed = (rnd.seed*9301+49297) % 233280;
  return rnd.seed/(233280.0);
};

function rand(number) {
  return Math.ceil(rnd()*number);
};

因为seed设置为时间;所以在时间变化后,取到的随机数会不同;只要seed不变。取到的数值就不变。

// 下面是在找资料的时候,很多小破站的代码,基本都是改编的;通过闭包,防止外部改变seed。
var rand = (function(){
  var today = new Date();
  var seed = today.getTime();
  function rnd(){
    seed = ( seed * 9301 + 49297 ) % 233280;
    return seed / ( 233280.0 );
  };
  return function rand(number){
    return Math.ceil(rnd(seed) * number);
  };
})();

在 1999 年,随机数市场发生了一个巨大的变化,Intel 在其 i810 芯片组上集成了芯片级的随机数生成器。这样使得新的服务器都自带热噪声的本地源随机数生成能力——真正的随机数生成器(TRNG),通过捕捉噪声来实现随机;

现在新的需求出现,实现不同概率,怎么实现?