简体   繁体   中英

Javascript - Get random number in range based on current date

Hello everyone and thank you for reading.

I'm trying to get a random number in a given range (in my case 1 - 87) based on the current date (no matter the format... milliseconds, YYYYMMDD, etc) and all this in javascript.

The reason for this is that I want to have a random number in this range that is different from day to day but remains the same during the day.

I first thought of simply generating a random number and then storing it in the cookies or localeStorage but I think that if you empty the browser cache or the localStorage (because yes my project is meant to be used on a browser) it will generate a new number when the page reloads and so this solution won't work.

Then I tried to use the seedRandom function of Davide Bau ( http://davidbau.com/archives/2010/01/30/random_seeds_coded_hints_and_quintillions.html ) but I didn't get the expected result (maybe I didn't understand how it works which is very likely too)

I would have shared with you a piece of code of my progress but none of the tests I did made sense to me, so I started from zero and I rely on you today.

Hoping to get some help, thanks !

Based on the ARNG algorithm that I found on the link you shared, you can use the current date (in my example, the timestamp format) as a seed for the RNG and always get the same random number from the list (1..87) given the same date.

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

Since the randomness is derived based on the date, you do not need to save anything in the localStorage or elsewhere. Your dates are the single point of reference when it comes to the random number generator.

You could format each date as a timestamp eg YYYYMMDD, then pass to a hahcode function such as cyrb53 (thanks bryc .).

We'd prepend our timestamp with a prefix to allow different sequences to be generated for the same dates if required.

We'd mod the hashcode with our maximum desired value (87 in this case) to get our random number for each day.

This number will be fixed for each day and prefix.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM