How is randomness achieved with Math.random in jav

2019-01-06 22:40发布

问题:

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.

回答1:

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

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



回答2:

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.



回答3:

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.



回答4:

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



回答5:

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