为什么“(seed * 9301 + 49297)%233280 / 233280.0”生成一个随机数?

时间:2015-11-15 06:14:04

标签: random

// Found this seed-based random generator somewhere
// Based on The Central Randomizer 1.3 (C) 1997 by Paul Houle (houle@msc.cornell.edu)

var seed = 1;

/**
 * return a random number based on a seed
 * @param seed
 * @returns {number}
 */
function getNextValue() {
    seed = (seed * 9301 + 49297) % 233280;
    return seed/(233280.0);
}

function setSeed(_seed_) {
    seed = _seed_;
}

module.exports = {
    nextValue: getNextValue,
    seed: setSeed
};

请参阅https://github.com/dylang/shortid/blob/master/lib/random/random-from-seed.js

2 个答案:

答案 0 :(得分:3)

  

为什么(seed * 9301 + 49297) % 233280 / 233280.0会生成一个随机数?

没有。它会生成一个完全确定的数字。结果序列乍一看可能看起来是随机的,因此这是一个伪随机生成器。更准确地说,它是linear congruential generator

你说你对“神奇”数字感到好奇。嗯,它们实际上是从一组几乎无限的数字中任意选择的。通常,出于数论的原因,使用素数系数(特别是作为除数)(主要是为了避免在生成的模式中非常明显的重复);然而,像这样的幼稚LCG会产生质量非常低的PRN,因此如果需要高质量的伪随机性,尝试调整LCG是没有意义的 - 只需使用更好的PRNG算法。

答案 1 :(得分:0)

它不是一个随机数生成器,而是一个基于提供的种子的伪随机数。重置种子将重置getNextValue并提供一致的输出。

正如评论所提到的,此代码基于The Central Randomizer。显然这段代码是因为Math.random在现在陈旧的Netscape 2中不起作用而创建的。反过来,这个实现基于现有的伪随机数生成器。有关此算法起源的更多信息,请参阅Original source of (seed * 9301 + 49297) % 233280 random algorithm?

技术上Math.random也是伪随机的,但您无法控制种子,因此此代码确实具有潜在有用的属性。如果你给它一个一致的种子,你将在重新加载时获得一致的输出。