Javascript -获取基于当前日期范围内的随机数

2eafrhcq  于 2022-12-25  发布在  Java
关注(0)|答案(2)|浏览(204)

大家好,感谢您的阅读。
我试图在给定的范围内(在我的例子中是1 - 87)根据当前的日期(无论格式...毫秒,YYYYMMDD等)和所有这些在javascript。
这样做的原因是,我希望在这个范围内有一个随机数,它每天都不同,但在一天中保持不变。
我首先想到的是简单地生成一个随机数,然后将其存储在cookie或localeStorage中,但我认为如果您清空浏览器缓存或localStorage(因为是的,我的项目是要在浏览器上使用的),它将在页面重新加载时生成一个新的数字,因此此解决方案将不起作用。
然后,我尝试使用Davide Bau(http://davidbau.com/archives/2010/01/30/random_seeds_coded_hints_and_quintillions.html)的seedRandom函数,但没有得到预期的结果(可能我不了解它是如何工作的,这也很有可能)
我本想和你们分享一段我的进步代码,但是我做的测试对我来说都没有意义,所以我从零开始,今天我依赖你们。
希望能得到一些帮助,谢谢!

fdx2calv

fdx2calv1#

根据我在您共享的链接中找到的ARNG算法,您可以使用当前日期(在我的示例中,时间戳格式)作为RNG的种子,并且总是从给定相同日期的列表(1..87)中获得相同的随机数。

<script src="//cdnjs.cloudflare.com/ajax/libs/seedrandom/3.0.5/lib/alea.min.js">
</script>
<script>
const arng = new alea(new Date().getTime());
const rand = Math.ceil( arng.quick() * 87 ); 
console.log( rand ); // <= Gives a random number between 1 and 87, 
// based on the timestamp seed
</script>

由于随机性是基于日期获得的,因此您不需要在localStorage或其他地方保存任何内容,您的日期是随机数生成器的唯一参考点。

mf98qq94

mf98qq942#

您可以将每个日期格式化为时间戳,例如YYYYMMDD,然后传递给hahcode函数,例如cyrb53(感谢bryc!)。
我们会在时间戳前面加上一个前缀,以便在需要时为相同的日期生成不同的序列。
我们将用最大期望值(本例中为87)对散列码进行模运算,以获得每天的随机数。
此数字将固定为每一天和前缀。

const prefix = '8tHifL4Cmz6A3e8';

/** From: bryc: https://github.com/bryc/code/blob/master/jshash/experimental/cyrb53.js **/
const cyrb53 = (str, seed = 0) => {
  let h1 = 0xdeadbeef ^ seed,
    h2 = 0x41c6ce57 ^ seed;
  for (let i = 0, ch; i < str.length; i++) {
    ch = str.charCodeAt(i);
    h1 = Math.imul(h1 ^ ch, 2654435761);
    h2 = Math.imul(h2 ^ ch, 1597334677);
  }

  h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^ Math.imul(h2 ^ (h2 >>> 13), 3266489909);
  h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^ Math.imul(h1 ^ (h1 >>> 13), 3266489909);

  return 4294967296 * (2097151 & h2) + (h1 >>> 0);
};

const maxN = 87;
const dateCount = 100;
const startDate = new Date();

const dates = Array.from({ length: dateCount }, (v, k) => { 
    const d = new Date(startDate);
    d.setDate(d.getDate() + k);
    return d;
})

function getTimestamp(date) {
    const dateArr = [date.getFullYear(), date.getMonth() + 1, date.getDate()];
    return dateArr.map(s => (s + '').padStart(2, '0')).join('')
}

const timeStamps = dates.map(d => getTimestamp(d));

console.log(timeStamps.map(timestamp => { 
    return { timestamp, randomNumber: 1 + cyrb53(prefix + timestamp) % maxN };
}))
.as-console-wrapper { max-height: 100% !important; }

相关问题