 I am the fourth and final mark speaking at this conference. So yeah, so I'm mark, follow me on Twitter at markwunch. After this talk, I will be unleashing a tweet storm of all of the things that I couldn't fit into this talk. Because I'm gonna be talking about randomness in computing. Randomness is a very broad topic. So this will be a high level survey and I hope to provide you a lot of jumping off points to explore things in more detail on your own. I have spent a very good portion of my career explaining that JavaScript and Java are not the same thing. This is both. So that's annoying. Chances are you have encountered this very function or something similar to it or you've touched some higher abstraction that calls it. So math.random produces a random number. But where does that number come from? How did it get here? Why this number? So this is a good joke. Get random number return four from XKCD. This might as well be the implementation. It's guaranteed to be random. Obviously things are a bit more complicated than this. So random number generation in computers is quite a lot like a coin flip. It's binary, it's heads or tails, it's zero or one. And we can approach random number generation the same way. The probability of getting heads is the same as getting tails. So we are equally likely to observe a zero or a one. So how do we teach a computer to flip a coin? And also flipping a coin is kind of a tedious way to get a lot of numbers. So how did people get a lot of random numbers before computers? They read a book published in 1955 by the Rand Corporation. You can judge this book by its cover. It's a million random digits. That's what's in the book. So scientists use this book to get random numbers for simulations. And what was especially helpful was that you could reproduce those simulations by referring to the same random numbers. Now the most notable thing about this book is its large number of humorous reviews on Amazon. So the idea of a book filled with nothing but random numbers seems so silly now but that's how they did it back then. There is no such thing as random numbers, said John Von Neumann. A computer can't generate random numbers because you can repeat that procedure and end up with the same sequence of numbers. Computers do math and you can't produce random numbers with math. It's deterministic. But what a computer can do is generate numbers that appear to be random. Algorithms generate numbers that approximate a random sequence. And we call that pseudo random, a PRNG, which is as close as we're going to get to an actual random number in software. So with something like dice or some physical way to produce randomness, physics are at play. Influences that a computer cannot reproduce. So a PRNG starts with a seed. This seed value is used in the algorithm to construct the initial state and from that numbers are produced. And so running a generator with the same seed will produce the same results. Here's an example. This is Mathematica and we're plotting random numbers. We're asking for a random number between zero and one, 10,000 times, and the animation that you see here is the seed value changing over time. And you can see that when we plot these numbers, we get the appearance of noise. So the numbers are uniformly distributed. Pseudo random means that the sequence has the properties of being random, but the output is repeatable. This is closure. This is the function you call to get a random number. This is how that function is defined and we see that it just calls back to our old Math.Random friend in Java. Here is how that function is defined. So I'll read some. When this method is first called, it creates a new pseudo random generator. It seems a little bit innocuous, but this bit of code is what got me personally really interested in this topic. Functional code is characterized by the absence of side effects. So that is from Mary Rose Cook. Yeah, whenever we call that closure code, it creates a new PRNG on the fly. So that is a big side effect in our presumably functional programming language. It's hiding what it does under the covers. And I bring this up because thinking functionally can help us better understand how these generators work. So let's look at Haskell. Here's how the random function is defined in Haskell. It's a function that takes a generator G and returns a pair of a random type A and another G. So when we look at this in the REPL, we call the makeStandardGen function and we give it a seed and we tell it we want back a pair of an int and a standard generator. So what it returns is a random number and after the comma a numeric representation of a generator. So if we call this function again, we get the exact same results. If we take the resulting generator and call random with that, we get the next number in the sequence. So showing this in the functional language like Haskell demonstrates that a PRNG is a state machine. Every time you output a number, you advance the state of the generator. So one area that functional programming and random number generation meet in a really awesome way is property-based testing. So like that found in QuickCheck or ScalaCheck. So this is a testing method where you test a program by generating a very large amount of random inputs and if the test fails, it can tell you exactly what state the generator was in when it failed so you can reproduce it. It's really awesome. This is also a link to a talk from last year that sews off a bunch of really interesting challenges in PRNGs for the purpose of making TestCheck, which is Clojure's property testing library. Okay, let's talk about PRNG algorithms. The Mersenne twister is a very widely used PRNG algorithm. Mersenne was the name of a French mathematician who's got a bunch of stuff named after him, including this twister. And I'm not entirely sure what this next bit means, but I can tell you that it's a twisted, linear feedback shift register. Usually when you see the Mersenne twister in the wild, you see this number along with it. It's a Mersenne prime, which is a prime number that is one less than a power of two. And this is the period or the cycle length of the Mersenne twister. So a period of a PRNG is how long it can produce numbers until the sequence begins to repeat. And that is a big number. This is one of those bigger than the number of atoms in the universe numbers that people just casually toss around. And of course, the twister doesn't hold them in memory all at once. And so that's the balancing act of a PRNG. It's period length, memory footprint, quality of results, and time. And different algorithms make different trade-offs. The Mersenne twister is the algorithm behind the random functions in a lot of programming languages. So Ruby, Python, Julia, to name just a few. The choice of your PRNG algorithm matters in really subtle ways. So these are two different plots from two different PRNGs. So you can see the top has like a discernible pattern. It's like a pair of corduroy's. And the bottom one looks more like static with less of a pattern. So it's visually more random. So the top is the output of the generator from V8, the JavaScript engine behind Chrome and Node. So just in December of last year, it was discovered that the PRNG there wasn't so great. And they've since changed it. But how do you know if your PRNG is good and not like the velvety velour of a pair of corduroy's? That it really produces high-quality pseudo-random stuff. Well, in 1995, what you would have done is you would have got yourself a CD-ROM and you would have run it through something called the Die Hard Battery of Tests, which are a suite of statistical tests that are meant to measure the quality of random number generators. There's also some newer, more rigorous tests now. There's Die Harder and Test U01. So that original V8 generator passed Die Hard, but not Test U01. All joking aside, this is kind of scary, actually. Here's a strongly worded quote from the Python documentation. This is from the Mersenne Twister homepage. And I think the main takeaway from this is that basically it's probably not cryptographically secure. Basically. So what does that mean? What does it mean to be cryptographically secure? So randomness is used in cryptography a lot, as we heard in Brennan's talk, to create nonces, salts, and keys. And in these cases, you want the next number in the PRNG sequence to be very, very hard to predict. And traditional PRNGs are a very common attack vector. And so even though the Mersenne Twister is a mainstay of many programming languages, there are algorithms that are designed for security. So the secure class of PRNGs are called cryptographically secure PRNGs or CSPRNGs. And they aren't better, but they balance those needs differently. So one CSPRNG algorithm I wanna highlight is Yaro. So if you use a Mac, you have this on your system. And one of the key parts of the design of these generators is that they reseed themselves. And one crypto trick is to make that seed very hard to predict. And to do this, CSPRNGs utilize something called an entropy pool. And you access the generator through the entropy device, which sounds so sinister. What's entropy? Entropy is the time between keystrokes or mouse movement or webcam noise or the turbulence in your spinning disk drive. So the generator will get a smidgen of real randomness from the hardware, from observed events, from the kernel, which writes entropy to a pool. And then that pool is used to seed the generator. And you can read randomness from the generator by reading from dev random, or you can write to the entropy pool by writing to this file. So I wanna leave you with some really useful stuff. I'm over time already. Here's a bash function called look busy. When you call it, just streams random numbers to your screen. And if someone is just casually walking by, it looks like you're really immersed in something. So this first line, this is how to roll a six-sided die in bash. This is how to roll a six-sided die in awk. And you can choose the seed in awk, and I think that's really cool. This next bit is Linux only, but it makes music from dev random. And if you're interested, just Google compose music from entropy. And finally, this is basic. This generates a pattern for a Commodore 64. This is also the name of a book. So if you Google 10 print, this is a book I'd recommend to anyone who is interested in learning more about this topic. So thanks very much for listening. Follow me at mark one. I'll be tweeting lots of follow-up stuff. I'll be posting these slides. Enjoy your lunch. Thanks very much.