Javascript -根据当前日期获取范围内的随机数



大家好,感谢大家的阅读。

我试图得到一个随机数在给定的范围内(在我的情况下1 - 87)基于当前日期(无论格式…毫秒,YYYYMMDD等)和所有这些在javascript。

这样做的原因是我想在这个范围内有一个随机数,每天都不同,但在一天中保持不变。

我首先想到的是简单地生成一个随机数,然后将其存储在cookie或localeStorage中,但我认为,如果您清空浏览器缓存或localStorage(因为是的,我的项目是要在浏览器上使用),它将在页面重新加载时生成一个新的数字,因此这个解决方案将不起作用。

然后我尝试使用Davide Bau (http://davidbau.com/archives/2010/01/30/random_seeds_coded_hints_and_quintillions.html)的seerandom函数,但我没有得到预期的结果(也许我不明白它是如何工作的,这很可能也是)

我本想和你分享一段我的进度代码,但我所做的测试对我来说都没有意义,所以我从零开始,今天我依靠你。

希望得到一些帮助,谢谢!

基于我在您共享的链接上发现的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或其他地方保存任何内容。当涉及到随机数生成器时,您的日期是唯一的参考点。

您可以将每个日期格式化为时间戳,例如YYYYMMDD,然后传递给哈希码函数,例如cyrb53(感谢bryc!)。

我们会在时间戳前加上一个前缀,以便在需要时为相同的日期生成不同的序列。

我们将用我们的最大期望值(在本例中为87)对哈希码进行mod,以获得每天的随机数。

此号码将固定为每一天和前缀。

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; }

最新更新