This brings up an obvious question. Okay. We don't want pseudorandom numbers, we want random numbers. How do we produce them? Where do these things come from? Well, let's look at some of the functions of the system. The first one that everyone sees, at least on Linux and Unix, is a function called rand(). It's a library function. It uses srand() to set a seed. You can also use sranddev() on some systems to get the generate a seed automatically from things within the kernel. The idea here is that what it uses in the kernel will be sufficiently random so that the seed itself will be random and then the sequence of numbers you get is going to be random. Typically, this is a 32 bit seed and a four byte internal state and the internal state is also 32-bits and the outputs a 32 bit number. For whatever it's worth, the early versions of this were not random at all. In some versions, in fact, the low bit alternated between zero and one. So, if you are planning on using a random number generator and the system you're using has this one, check it out and be sure it's not the original one. Be sure it's a different one. My own recommendation is not to use this for anything serious. Now, the systems also supply something called random(). It's another library function and it's very similar to rand() except it's statistically random. You can set up the initial state. It's an array used to hold the initial state and you give it a seed and the number of bytes in an array and that number of bytes in the array can be anywhere from eight to 256 bytes. It generates a 31 bit output. If you use the full array, that is, 256 bytes, the period, that is the time before this pseudorandom number generator begins to repeat itself, is over two to the 69th which is long enough for all practical purposes. However, it will repeat, which means it's a statistically random pseudorandom number generator, but it's not a cryptographic one. There are other library functions as well, lrand48() does signed random number generation between minus two to the 31st and two to 31st minus one. There are a variety of these. Drand() does it for real numbers from zero to one. Includes zero doesn't include one, lrand() is positive numbers and mrand() is both positive and negative numbers. Again, you set the seed using srand(). This is a better. However, it still pseudorandom. It's statistically random, but it's not cryptographically random. If you want cryptographic randomness, go to there, many systems there's something called arc4random(). Essentially, what you do is you look for a function that uses cryptography to generate random numbers. This one is based on a cipher called ARC4 which is pretty strong. Without going into the details of how ARC4 works, essentially what it does is it keeps track of state. It has over two to the 1,700 states. Again, which is very, very, very long. It returns an unsigned value between zero and two to the 32nd not including two to the 32nd. Also when you call it, automatically initializes itself. Now, the state is encompassed by what are called S-boxes. As you can see from this slide, it uses 64 8-bit S-boxes. We're not going to go into what an S-box is here other than to say it's a substitution of one set of bits for another. If you don't like the one you started with or you want to mix it up later on in the cipher, use arc4random_stir(). That function will generate a new set of 64 8-bit S-boxes. It uses data from a file called or rather from a device called /dev/urandom. Urandom stands for unsigned random. It's basically a file for a device that generates random numbers from the kernel and from other hardware things. So, this one is very good for cryptographic applications because you get cryptographically secure, cryptographic randomness.