views:

387

answers:

7

How is randomness achieved with Math.random in javascript? I've made something that picks between around 50 different options randomly. I'm wondering how comfortable I should be with using Math.random to get my randomness.

+5  A: 

From the specifications:

random():

Returns a Number value with positive sign, greater than or equal to 0 but less than 1, chosen randomly or pseudo randomly with approximately uniform distribution over that range, using an implementation-dependent algorithm or strategy. This function takes no arguments.

So the answer is that it depends on what JavaScript engine you're using.

I'm not sure if all browsers use the same strategy or what that strategy is unfortunately

Update: There's this question on StackOverflow that might provide some more insight.

Update #2: From that question above I got this link from Mozilla that says:

Returns a pseudo-random number in the range [0,1) — that is, between 0 (inclusive) and 1 (exclusive). The random number generator is seeded from the current time, as in Java.

So that's at least how it works in FireFox.

It should be fine for your purposes. Only if you're doing a large amount of numbers would you begin to see a pattern

Bob
@cocotow et al. I was wondering weather or not that psudo-randomness is good or not? like i would guess that its porobobly not good enough for vegas or science but is it good enough for everyday needs? (i made osmething that will make decisions for me based off of a list of possible decisisons.
David
It's good enough for everyday needs, which is what Javascript's `Math.random()` is for. That's fine.
John Feminella
+1  A: 

It's 100% random enough for your purposes. It's seeded by time, so every time you run it, you'll get different results.

Paste this into your browsers address bar...

javascript:alert(Math.random() * 2 > 1);

and press [Enter] a few times... I got "true, false, false, true" - random enough :)

Timothy Khouri
Your code example doesn't show the randomness of the random generator, as you have introduced a skew. It will result in more false values than true values. A very slight difference, but still an example of how you can reduce the quality of the randomness by using it wrong.
Guffa
True... but if I had 50 check boxes... even the *sample* that I gave would be good enough for the David's question.
Timothy Khouri
+2  A: 

I'm wondering how comfortable i should be with using Math.random to get my randomness.

You should be extremely skeptical of, if not outright rejecting, the assumption that Math.random() is a good source of randomness. Many implementations of Math.random() have weak entropy pools and don't provide good randomness at all. An attacker executing Math.random() many times can deduce the internal state of the generator (and thus replicate it locally), enabling them to predict all future "random" outcomes from that client.

For example, see this security issue from Juniper, which flags over 100 browser versions as being too leaky with their entropy pools.

John Feminella
The guy is asking for switching 50 random options... seriously, it's fine.
Timothy Khouri
+1  A: 

The exact implementation can of course differ somewhat depending on the browser, but they all use some kind of pseudo random number generator. Although it's not really random, it's certainly good enough for all general purposes.

You should only be worried about the randomness if you are using it for something that needs exceptionally good randomness, like encryption or simulating a game of chance in play for money, but then you would hardly use Javascript anyway.

Guffa
+1  A: 

It depends on the browser engine.

For the V8 JavaScript engine used in Google Chrome, you can check out the source here.

Nick Presta
+2  A: 

This is a little overkill...but, I couldn't resist doing this :)

You can execute this in your browser address bar. It generates a random number between 0 and 4, 100000 times. And outputs the number of times each number was generated and the number of times one random number followed the other.

I executed this in Firefox 3.5.2. All the numbers seem to be about equal - indicating no bias, and no obvious pattern in the way the numbers are generated.

javascript:
var max = 5;
var transitions = new Array(max);
var frequency = new Array(max);
for (var i = 0; i < max; i++)
{
     transitions[i] = new Array(max);
}
var old = 0, curr = 0;
for (var i = 0; i < 100000; i++)
{
   curr = Math.floor(Math.random()*max);
   if (frequency[curr] === undefined) 
   {
      frequency[curr] = -1;
   }
   frequency[curr] += 1;
   if (transitions[old][curr] === undefined)
   {
      transitions[old][curr] = -1;
   }
   transitions[old][curr] += 1;
   old = curr;
}
alert(frequency);
alert(transitions);
aip.cd.aish
A: 

Using Math.random() is fine if you're not centrally pooling & using the results, i.e. for OAuth.

For example, our site used Math.random() to generate random "nonce" strings for use with OAuth. The original JavaScript library did this by choosing a character from a predetermined list using Math.random(): i.e.

for (var i = 0; i < length; ++i) {
    var rnum = Math.floor(Math.random() * chars.length);
    result += chars.substring(rnum, rnum+1);
}

The problem is, users were getting duplicate nonce strings (even using a 10 character length - theoretically ~10^18 combinations), usually within a few seconds of each other. My guess this is due to Math.random() seeding from the timestamp, as one of the other posters mentioned.

Nick Baicoianu