WEBVTT

00:00.180 --> 00:05.550
Hello again! In this video, we are going to look at how to get a random number in older versions of

00:05.550 --> 00:12.240
C++. C has a function called rand(), which C++ has inherited.

00:12.870 --> 00:19.410
This is a pseudo-random number generator, so it will generate a sequence of numbers which look random.

00:19.980 --> 00:23.220
And each time we call rand(), we get the next number from the sequence.

00:24.090 --> 00:27.870
If we get to the end of the sequence, then it just goes back to the beginning, and starts again.

00:28.710 --> 00:35.760
The return value is an integer between 0 and RAND_MAX. And RAND_MAX is chosen by the implementation,

00:36.120 --> 00:37.560
so there is no standard.

00:38.940 --> 00:39.850
So this is what we do,

00:40.020 --> 00:49.620
to get a random number. And your random number today is 41. And that is OK if you want some random number between 0

00:49.620 --> 00:54.900
and RAND_MAX, whatever that is. But you may want a different range of values.

00:55.650 --> 00:59.430
And in that case, you have to do some arithmetic and rescale the result.

01:00.180 --> 01:06.180
For example, if we want a floating point number between 0 and 1, we divide the return value

01:06.180 --> 01:07.230
by RAND_MAX.

01:08.040 --> 01:13.650
But we have to be careful, because these are both integers. So that will be an integer division. So we only

01:13.650 --> 01:14.760
get 0 or 1.

01:15.900 --> 01:21.180
So we need to make sure we do a floating-point division, and to do that, we convert the result of

01:21.180 --> 01:23.280
rand() to a floating point number.

01:25.140 --> 01:30.240
If we want the range to start from a different value, then we have to add that, after re-scaling.

01:30.870 --> 01:34.860
So if we want integers between 1 and 100, we have to re-scale,

01:35.280 --> 01:38.910
to get integers between 0 and 99, and then add 1.

01:41.280 --> 01:42.630
So let's try that out.

01:44.370 --> 01:48.090
So that is a floating-point number between 0 and 1.

01:48.540 --> 01:51.810
And then we have 10 integers between 1 and 100.

01:53.280 --> 01:56.670
And if I run it again, we get the same numbers.

02:01.750 --> 02:05.260
If we want different random numbers, we have to "seed" the generator.

02:05.830 --> 02:07.630
We do that by calling srand().

02:08.440 --> 02:10.180
We pass the seed number as

02:10.180 --> 02:16.000
the argument. And the traditional practice here is to pass the current time, because what could be more

02:16.000 --> 02:16.930
random than the time?

02:17.410 --> 02:18.610
There is no way of guessing that, is there (!?)

02:18.610 --> 02:21.700
There is another C function, called time().

02:22.270 --> 02:27.040
If we call this with argument 0, it will return the current time, as a very large integer.

02:27.430 --> 02:33.040
The number of seconds since 1970. And then that can be used to seed the random number generator.

02:34.540 --> 02:39.250
In addition to the obvious problem, the value returned by time only changes once per second.

02:40.690 --> 02:44.800
So if you have another program which starts up at the same time, it will have the same seat and it is

02:44.800 --> 02:46.690
going to generate the same sequence of random numbers.

02:47.050 --> 02:50.650
And this does make it a bit easier for people who are trying to guess the sequence.

02:52.390 --> 02:57.550
So here is the same code again, with our call to srand(), using the current time as the seed.

02:59.420 --> 03:03.410
So if I wait one second, I should get different numbers.

03:05.810 --> 03:09.200
I do not think I can type this fast enough to do it twice in one second!

03:09.350 --> 03:12.800
Maybe you could do that from the command line, actually. Something for you to try out!

03:15.300 --> 03:20.850
OK, so that all seems pretty straightforward, so why does it need to change? If you are just writing

03:20.880 --> 03:23.850
"toy" programs, then this approach is good enough.

03:24.630 --> 03:27.780
If you are serious about random numbers, then there are quite a few issues.

03:29.040 --> 03:33.310
The first one is this the implementer can use any algorithm they want.

03:33.330 --> 03:37.380
There is no standard. And apparently there have been some pretty shocking ones in the past.

03:38.550 --> 03:41.910
The present implementations are probably okay, but not great.

03:43.650 --> 03:48.900
There's a common tendency to generate numbers which are not particularly random. Especially if you look

03:48.900 --> 03:51.720
at the last few digits. And quite a few people do that.

03:52.230 --> 03:57.360
So she gets a random number between 0 and 1000, say, they just chop off everything except the last

03:57.360 --> 03:58.050
few digits.

03:58.410 --> 03:59.880
That is not really a very good approach.

04:00.450 --> 04:06.690
If we do not want numbers between 0 and RAND_MAX, we have to re-scale the range, and most implementations

04:06.690 --> 04:08.070
are not very robust to this.

04:08.670 --> 04:14.430
If you re-scale the range, it introduces what is called "bias", and that means that some numbers are more

04:14.430 --> 04:15.240
likely than others.

04:15.870 --> 04:18.870
So the results are not quite as random as they should be.

04:22.610 --> 04:27.680
And finally, the sequence is too short, and it repeats too often, and guessing the next number is not

04:27.680 --> 04:28.640
as hard as it should be.

04:29.030 --> 04:31.490
So this is really not good enough for cryptography.

04:32.450 --> 04:34.130
Okay, so that is it for this video.

04:34.520 --> 04:35.390
I will see you next time.

04:35.630 --> 04:37.490
Until then, keep coding!
