2

I have an array which is being get by a HTTP request every times the user reloads the page, and I want to shuffle it daily.

I want this array to be shuffled day by day and keep the same array the whole day, for all the users. The shuffle order has to be set the first time a user is getting this array and have to be the same for all users the whole day, beginning at midnight, every time the array is beign get by the request.

Then the next day, shuffle again for all users, the whole day but differently. And so on.

Here's my shuffle function:

function shuffle (array) {
let currentIndex = array.length; let randomIndex

// While there remain elements to shuffle...
while (currentIndex !== 0) {
  // Pick a remaining element...
  randomIndex = Math.floor(Math.random() / 10) * currentIndex)
  currentIndex--;

  // And swap it with the current element.
  [array[currentIndex], array[randomIndex]] = [
    array[randomIndex], array[currentIndex]]
}

return array

}

I'm not so good at algorithmic (only basics) and some help on this would be welcome.

Thanks !

Pierrick Martellière
  • 1,554
  • 3
  • 21
  • 42
  • 4
    A good idea might be to use a deterministic pseudo-random number generator, and use some characteristic of the day as the seed. You can use something simple such as the date, if you don't care about users being able to reverse-engineer and "guess" tomorrow's values; or you can use something more complex and unpredictable such as the weather forecast or the stock market, if you want values to be unpredictable; see for instance [xkcd: GeoHashing](https://xkcd.com/426/) – Stef Sep 28 '21 at 15:30
  • 1
    Then once you have chosen your pseudo-random number generator, you can just trust your programming language's standard `shuffle` function, assuming the documentation tells you that you can choose the number generator for that function (or at least, that you can set the seed yourself). – Stef Sep 28 '21 at 15:32
  • 1
    Your code is more or less an implementation of [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle), except the pseudo-random number you're using is `Math.floor((new Date().getDay / 10) * currentIndex)`, which looks suspiciously not random, and also could exceed `current_index`, since I assume `.getDay` returns a value between 1 and 31. – Stef Sep 28 '21 at 15:35
  • Hi @Stef , I updated my code to the original function. It's using Mzath.random which is returning a random float number which is between 0 and 1. What should I put in like localStorage every day to use only this randomisation in place of Math.random please ? Math.random doesn't permit to use a seed. I'm really novice in algorithm and security programming – Pierrick Martellière Sep 28 '21 at 16:11
  • The date would be perfect for the seed, since this array is an array of public products. – Pierrick Martellière Sep 28 '21 at 16:12
  • Date.getDay() is returning the day of the week starting with 0 for sunday. – Pierrick Martellière Sep 28 '21 at 16:13
  • 1
    `Date.getDay()` is a bit too weak: it means that every 7 days, your array would be shuffled exactly the same. Perhaps you should use a more unique number, such as the full date (including year, month, day), or "the number of seconds since Jan 1st 1901 midnight and today midnight", or something similar. Then read the link given in @btilly 's answer: it's not possible to provide a custom seed with Math.random(), but it's possible to use another pseudo-random number generator and provide it with a seed. – Stef Sep 28 '21 at 16:16
  • 1
    assuming your pseudo-random number generator function is called `prng` and has been properly seeded and returns a number between 0 inclusive and 1 exclusive, then you should probably use `randomIndex = Math.floor(prng() * currentIndex)` – Stef Sep 28 '21 at 16:18
  • Thank you very much :) – Pierrick Martellière Sep 29 '21 at 19:55

1 Answers1

2

Your code looks like it might be JavaScript. If so, look at Seeding the random number generator in Javascript for seedable random number generators. Use that to make the random decisions with your current sorting algorithm.

I would suggest starting with a seed that is a hash of some fixed garbage string and the current date. This will change once a day, but the information about what you got yesterday won't leak the secret of the fixed garbage string.

btilly
  • 43,296
  • 3
  • 59
  • 88