Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

True or better Random numbers with Javascript

I have all kinds of resources that rely on javascript random numbers. However, I've been seeing a lot of problems where random isn't so random because of the way I'm generating random numbers.

Is there any javascript resource for me to generate true, or just better random numbers?

I know that I can interface with Random.org, but what other options do I have?

I'm using:

function rand( lowest, highest){     var adjustedHigh = (highest - lowest) + 1;            return Math.floor(Math.random()*adjustedHigh) + parseFloat(lowest); } 
like image 448
rlb.usa Avatar asked Oct 01 '12 12:10

rlb.usa


People also ask

How good is JavaScript math random?

The JavaScript Math. random() method is an excellent built-in method for producing random numbers. When Math. random() is executed, it returns a random number that can be anywhere between 0 and 1.

Is JavaScript random actually random?

In JavaScript, random() is a built-in method that is used to return a random number in the range 0 to 1 (with 0 being inclusive and 1 exclusive). The distribution of the generated random numbers is approximately uniform. It does not actually return a whole number. Instead, it returns a floating point (decimal) value.

Is JavaScript math random safe?

random() Note: Math. random() does not provide cryptographically secure random numbers. Do not use them for anything related to security.

Is math random () biased?

The problem with this approach is that it's biased. There are numbers returned that are more likely to occur than others. To understand this, you need to understand that Math. random() is a 32-bit RNG in Chrome and Safari, and a 53-bit RNG in Edge and Firefox.


2 Answers

Assuming you're not just seeing patterns where there aren't any, try a Mersenee Twister (Wikipedia article here). There are various implementations like this one on github.

Similar SO question:

Seedable JavaScript random number generator

If you want something closer to truly random, then consider using the random.org API to get truly random numbers, although I would suggest only using that to seed, not for every number, as you need to abide by their usage limits.

like image 68
Phil H Avatar answered Oct 10 '22 14:10

Phil H


Tweaking numbers so they "look random"

I agree with Phil H that humans are so good at finding patterns that they often think they see patterns even in "perfectly random" sequences of numbers (clustering illusion, apophenia, gambler's fallacy, etc).

Plots of true random positions generally have lots of clumps and points that "coincidentally" fall very close together, which looks pretty suspicious.

Artists often take completely randomly generated patterns and "nudge" them to make them appear "more random", even though that careful nudging actually makes the pattern less random (a), (b), (c), (d), etc.

Alternatively, a low-discrepancy sequence sometimes "looks better" than a true random sequence and is much faster to generate.

Fast random number generators

There are many "random number generators" across a whole spectrum from "extremely fast" to "relatively slow" and from "easy for even a human to see patterns" to "unlikely that unassisted humans could ever see any patterns" to "cryptographically secure and, after seeded with adequate amounts of entropy, as far as we can tell, indistinguishable from random to any attacker using less than all the energy produced by humanity for a month."

Non-cryptographic-strength random number generators that still give excellent output (unlikely that unassisted humans could ever see any patterns) include the Mersenne twister, multiply-with-carry, Lagged Fibonacci generator, Well equidistributed long-period linear, Xorshift, etc.

Cryptographic random number techniques that work with some browsers

I hear that Cryptocat and other JavaScript applications use the convenient window.crypto.getRandomValues() or window.msCrypto.getRandomValues() or SubtleCrypto.generateKey() functions that are designed to generate cryptographic random numbers. Unfortunately, that function is not available in IE 11 and below.

Since web browsers use random numbers all the time (for every "https://" page they fetch), it's quite likely that these functions (where available) may run faster than most random number generators written in JavaScript -- even non-cryptographic algorithms.

Cryptographic random number techniques compatible with ancient and modern browsers

One way to generate true random numbers in JavaScript is to capture mouse events and add them into a pool of entropy, keeping track of some (hopefully conservative) estimate of the entropy added. Once the pool is "full" (estimates indicate that at least 128 bits of entropy have been added), use some cryptographically secure random number generator to generate random numbers from the pool -- typically by using a one-way hash so that a sequence of a few thousand output numbers are not enough to deduce the state of the entropy pool and hence predict the next output number.

One implementation: http://lightsecond.com/passphrase.html

Further reading

  • window.crypto
  • Compatibility of window.crypto.getRandomValues()
  • Secure random numbers in javascript?
  • https://security.stackexchange.com/questions/20029/generate-cryptographically-strong-pseudorandom-numbers-in-javascript
  • Is there any built in browser support for crypto random numbers in IE and Webkit? Firefox has window.crypto
  • Better random function in JavaScript
like image 37
David Cary Avatar answered Oct 10 '22 15:10

David Cary