|
| 1 | +# Introduction |
| 2 | + |
| 3 | +Many programs need (pseudo-)random values to simulate real-world events. |
| 4 | + |
| 5 | +Common, familiar examples include: |
| 6 | + |
| 7 | +- A coin toss: a random value from ('H', 'T'). |
| 8 | +- The roll of a die: a random integer from 1 to 6. |
| 9 | +- Shuffling a deck of cards: a random ordering of a card list. |
| 10 | +- The creation of trees and bushes in a 3-D graphics simulation. |
| 11 | + |
| 12 | +Generating truly random values with a computer is a [surprisingly difficult technical challenge][why-randomness-is-hard], which is why there are also "pseudorandom" generators. |
| 13 | + |
| 14 | +<!-- prettier-ignore --> |
| 15 | +~~~exercism/advanced |
| 16 | +[The language specification][spec] for JavaScript doesn't force the implementation for random number generation. |
| 17 | +All major browsers and JavaScript runtimes implement a PRNG (pseudo-random number generator). |
| 18 | +Because the numbers are not cryptographically secure, they should never be used for anything that requires true or at least cryptographically secure random numbers, such as certificate or password generation or operations. |
| 19 | +
|
| 20 | +There is a standard called [Web Cryptography][rfc] which standardizes an interface for doing cryptography in JavaScript. |
| 21 | +It is implemented [by Browsers][crypto-web] as well as runtimes such as [Node.JS][crypto-node] and [Deno][crypto-deno]. |
| 22 | +
|
| 23 | +This concept is not about Web Crypto and will restrict itself to pseudo-random number generation. |
| 24 | +
|
| 25 | +[rfc]: https://www.w3.org/TR/webcrypto-2/ |
| 26 | +[spec]: https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-math.random |
| 27 | +[crypto-web]: https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues |
| 28 | +[crypto-node]: https://nodejs.org/api/webcrypto.html#cryptogetrandomvaluestypedarray |
| 29 | +[crypto-deno]: https://docs.deno.com/api/web/~/Crypto |
| 30 | +~~~ |
| 31 | + |
| 32 | +## Generating random numbers |
| 33 | + |
| 34 | +In Javascript, you can generate psuedorandom numbers using the [`Math.random()`][Math.random] function. |
| 35 | +It will return a psuedorandom floating-point number between 0 (inclusive), and 1 (exclusive). |
| 36 | + |
| 37 | +To get a random number between _min_ (inclusive) and _max_ (exclusive) you can use a function something like this: |
| 38 | + |
| 39 | +```javascript |
| 40 | +function getRandomInRange(min, max) { |
| 41 | + return min + Math.random() * (max - min); |
| 42 | +} |
| 43 | +getRandomInRange(4, 10); |
| 44 | +// => 5.72 |
| 45 | +``` |
| 46 | + |
| 47 | +<!-- prettier-ignore --> |
| 48 | +~~~exercism/advanced |
| 49 | +Most simple techniques of returning a range of numbers based on the randomly generated number [will introduce bias][bias]. |
| 50 | +That means that some numbers will be more likely to be rolled than others. |
| 51 | +Using the multiplication technique spreads out the bias over the entire range, so it will be less obvious and in most cases not a big issue, but you should be aware of this. |
| 52 | +
|
| 53 | +[bias]: https://adammil.net/blog/v134_Efficiently_generating_random_numbers_without_bias.html |
| 54 | +~~~ |
| 55 | + |
| 56 | +## Generating random integers |
| 57 | + |
| 58 | +To generate a random integer, you can use `Math.floor()` or `Math.ceil()` to turn a randomly generated number into an integer. |
| 59 | + |
| 60 | +[why-randomness-is-hard]: https://www.malwarebytes.com/blog/news/2013/09/in-computers-are-random-numbers-really-random |
| 61 | +[Math.random]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random |
0 commit comments