3

I am trying to create a function that takes 4 parameters and spits out a random number. But I want it so if the same 4 parameters are input, you will always get the same answer. The number should be between 0 and the max argument.

function random (x,y,z,max) {
    output = ;
    return Math.floor(output * max); 
}

Is there any simple forumala I can use to get this? I tried to create one but it didn't look random at all, and would look very similar if you changed one parameter very slightly. I want it to be completely different, but repeatable.

hash function:

function hash (input){
    input = 'random'+input;
    var hash = 0;
    if (input.length == 0) return hash;
    for (i = 0; i < input.length; i++) {
        char = input.charCodeAt(i);
        hash = ((hash<<5)-hash)+char;
        hash = hash & hash; // Convert to 32bit integer
    }
    return Math.abs(hash);
}
stackers
  • 2,701
  • 4
  • 34
  • 66
  • random should be not predictable – Nina Scholz Dec 12 '15 at 19:21
  • This is impossible, obviously. As Nina said you can't predict a random number. That's not random. If you want a formula that comes up with a number then just write whatever you want. The world's your oyster pal. – JBux Dec 12 '15 at 19:24
  • Okay then random isn't the right word, but I described what I'm trying to do. It should seem random. – stackers Dec 12 '15 at 19:29
  • Can you evaluate the quantity of this function calls in one session? My approach is to use some cache layer. If there is no value for current x-y-z combination, then generate a new random value and store it in the cache for later usage. – Max Zuber Dec 12 '15 at 19:40
  • Another approach is to use some crypto library to calculate hash of the string, based on x, y and z concatenation, and normalize the result to 0...1 interval. – Max Zuber Dec 12 '15 at 19:55
  • I've got the hashing part down, but I get a big integer, how do I turn that into a number between 0 and 1? – stackers Dec 12 '15 at 20:09
  • @stackers Use proportion: divide your calculated hash value to max possible hash value, it depends on the function. – Max Zuber Dec 12 '15 at 20:58
  • is there a way to figure that out? I don't really understand the math. I added my hash function above. – stackers Dec 13 '15 at 05:31

2 Answers2

3

Generating an apparently unpredictable data from another is called "hashing"; restricting it to a range is called "modulo". Here is an easy way to do hashing using exponentiation:

const hashLim = () => {
  const args = Array.prototype.slice.call(arguments);
  const limit = args.shift();
  var seed = limit - 1;
  
  for (a in args) {
    seed = Math.pow(args[a] + limit, seed) % limit
  }
  return seed;
}

document.write(hashLim(100, 4, 16, 64) + '<br/>')
document.write(hashLim(100, 5, 16, 64))
Michael Lorton
  • 43,060
  • 26
  • 103
  • 144
  • so this returns a number up to the input right? Is there a way to add multiple numbers? – stackers Dec 13 '15 at 05:22
  • 1
    @stackers, this answer should be the accepted one (click the check mark). It's the only answer that provides a deterministic and reasonably efficient PRN function. It's also very flexible on the number of input parameters. I would upvote twice if I could. – LarsH Jan 05 '17 at 15:49
0

You can use some self made calculation for pseudo random values, like this example with pi and the taking of only the fractal part.

function Random(seed) {            
    var r = seed;
    this.random = function () {
        var v = r * Math.PI;
        r = v - (v | 0);
        return r;
    }
    this.random();
}

var i,
    q = new Random(42),
    r = new Random(42);
for (i = 0; i < 10; i++) {
    document.write(q.random() +'<br>'+ r.random() + '<hr>');
}
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392