Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,544
6,042
Is there a good, portable random number generator available for C++?

By "good", I mean I don't have to include a line of code to seed it, it'll be different with each run of the program, and the pattern won't be apparent.

I know that rand() is available, but issues with it include:
1 - You have to seed it.
2 - It's implementation dependent, and there's no requirement for it to actually have a non-predictable pattern. An implementation could be as simple as:

Code:
int rand() {
    return 0;
}

And it would conform to C99's definition of rand(). (Am I using the right terms here?)

If I were writing this program for just OS X and iOS, I'd use arc4rand()... does anyone have anything comparable I could use in C++?
 

chown33

Moderator
Staff member
Aug 9, 2009
10,706
8,346
A sea of green
Google the source for arc4rand.

I did it myself a while ago, because I needed a PRNG in an embedded microcontroller project. It wasn't hard to find C implementations.

You will still need a source for initial entropy, and that source may need to be tailored to the platform. For example, one of the default sources in the source I got was the uninitialized stack area. On an embedded uC, that's an extremely predictable source, because the call sequence that leads up to the initialization is always identical. So for me, the hard part wasn't the PRNG itself, but coming up with a usable source of initial entropy.

A typical default source on a non-embedded computer is the /dev/random device (or its equivalent). If you know that device will be present, use it. Otherwise the task of gathering entropy becomes harder.
 

ytk

macrumors 6502
Jul 8, 2010
252
5
Code:
cout << "Please roll a die and type in the result: " ;
cin >> result ;

:D

Seriously, though, any pseudorandom number generator is going to have to be seeded somehow, and will by definition have a predictable pattern. The only way around this is with a dedicated hardware random number generator (of which, technically, a thrown die is an example).

As chown33 said, if the problem is that you don't have any way of generating the initial entropy required to seed the generator on your system, then you're simply not going to find any library that will work for you. If you do have access to something like a continuously running timer, then what's the problem with seeding? If you really want, you can write a wrapper around random() (which is a better replacement for rand() and already part of stdlib.h) that reseeds the PRNG each time you call it. That would make it less "predictable", anyway, assuming you didn't call it so quickly that you ever generate numbers with the same random seed twice in succession.
 

jon3543

macrumors 6502a
Sep 13, 2010
608
265
Is there a good, portable random number generator available for C++?

Several are part of the C++ Standard and should come with any compiler that has kept up over the last few years. Have you looked for:

#include <random>

Your other requirements are either easy to deal with or impossible to achieve using ordinary equipment.
 

phr0ze

macrumors 6502a
Jun 14, 2012
513
0
Columbia, MD
Is there a good, portable random number generator available for C++?

By "good", I mean I don't have to include a line of code to seed it, it'll be different with each run of the program, and the pattern won't be apparent.

I know that rand() is available, but issues with it include:
1 - You have to seed it.
2 - It's implementation dependent, and there's no requirement for it to actually have a non-predictable pattern. An implementation could be as simple as:

Code:
int rand() {
    return 0;
}

And it would conform to C99's definition of rand(). (Am I using the right terms here?)

If I were writing this program for just OS X and iOS, I'd use arc4rand()... does anyone have anything comparable I could use in C++?

I would begin by looking for code samples to the generators discussed here: http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,565
Open terminal, enter "man arc4random" and read carefully.

You can't produce better random numbers. Well, if you can, you are not looking for advice on macrumors :D
 

Cromulent

macrumors 604
Oct 2, 2006
6,802
1,096
The Land of Hope and Glory
Open terminal, enter "man arc4random" and read carefully.

You can't produce better random numbers. Well, if you can, you are not looking for advice on macrumors :D

I'd be curious how the new random number generator built into modern Intel CPUs compares to this in terms of quality. Since the Intel implementation contains a hardware based entropy source I would guess it was better. It would definitely be faster.

http://en.wikipedia.org/wiki/RdRand
 

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,544
6,042
I'd be curious how the new random number generator built into modern Intel CPUs compares to this in terms of quality. Since the Intel implementation contains a hardware based entropy source I would guess it was better. It would definitely be faster.

http://en.wikipedia.org/wiki/RdRand

This is very cool, but unfortunately, as chown said, not sufficiently portable.

I'd like my app to run on darn near any OS... OS X, iOS, Android, Windows XP, 7, RT, or 8... and it must be C++. So being able to seed with a clock isn't an actual issue, but I prefer systems where I don't need to handle seeding (IE, the way arc4rand() doesn't need to be seeded first.)
 

ytk

macrumors 6502
Jul 8, 2010
252
5
:confused: What's the point of bloating your program unnecessarily with some third-party random number library instead of just using the perfectly good built-in random number function, all to avoid a single line of code?
 

Mr. Retrofire

macrumors 603
Mar 2, 2010
5,064
518
www.emiliana.cl/en
A typical default source on a non-embedded computer is the /dev/random device (or its equivalent). If you know that device will be present, use it. Otherwise the task of gathering entropy becomes harder.
Other device/machine specific information includes:
- Current configuration data in preference files (user specific).
- Current uptime (microseconds or nanoseconds).
- Number of files in a certain folder (user specific).
- All names of all files in a certain folder (user specific).
- Noise from the microphone & camera pictures (user specific).
- Random seed files from other (open source) applications (openssl for example).

For preshared keys (SHA-2 (512-Bit) or SHA-3 based), i would use noise from a non-silent street/city recorded via a stereo recorder like the WS-803 or WS-813. This device supports the lossless PCM format in WAV files (41 kHz). If someone can predict 1 GB of this noise, then i'm the emperor of china! ;-)
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,565
:confused: What's the point of bloating your program unnecessarily with some third-party random number library instead of just using the perfectly good built-in random number function, all to avoid a single line of code?

Which "perfectly good built-in random number function" do you mean? The one in the Standard C library?
 

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,544
6,042
Which "perfectly good built-in random number function" do you mean? The one in the Standard C library?

I would assume that's what they meant.

I have, for the time being, decided to just use it and, to ensure "fairness" to the best of my ability, I include something like:

Code:
unsigned char n = (from user input);
int maxFairRand = (MAX_RAND / n) * n;
int rand = random();
while (rand > maxFairRand)
    rand = random();
unsigned char r = rand % n

As much as I can control it, this ensures that lower numbers won't be more common than higher numbers. (All of my numbers are 255 or lower... Thus why r and n are both unsigned chars.)

I'm just doing a school homework assignment that involved an RNG as a portion of it. I figure overdoing an assignment is always fun, so I tried that here.
 

osxabsd

macrumors member
Sep 28, 2009
41
0
seed sources

Any thoughts on these for "random seeds"
Internal: system clock milliseconds
External: Earthquake web site richter scale fractions.
 

gnasher729

Suspended
Nov 25, 2005
17,980
5,565
I would assume that's what they meant.

I have, for the time being, decided to just use it and, to ensure "fairness" to the best of my ability, I include something like:

Code:
unsigned char n = (from user input);
int maxFairRand = (MAX_RAND / n) * n;
int rand = random();
while (rand > maxFairRand)
    rand = random();
unsigned char r = rand % n

As much as I can control it, this ensures that lower numbers won't be more common than higher numbers. (All of my numbers are 255 or lower... Thus why r and n are both unsigned chars.)

I'm just doing a school homework assignment that involved an RNG as a portion of it. I figure overdoing an assignment is always fun, so I tried that here.

Well, arc4random_uniform (n) does exactly that and I can guarantee that it will be of higher quality. And it automatically has a random seed. Some implementations of random () are of pathetic quality. For example, if you throw two dice until you get two different results, what is the probability that the first dice shows a higher number than the second? There are random number generators out there where the answer is not "50%".

----------

Any thoughts on these for "random seeds"
Internal: system clock milliseconds
External: Earthquake web site richter scale fractions.

Internal: date in nanoseconds, xor'd with the time since the computer has started in processor cycles.

Better: /dev/random.
 

ytk

macrumors 6502
Jul 8, 2010
252
5
Which "perfectly good built-in random number function" do you mean? The one in the Standard C library?

random(). If your primary concern is portability, why use anything else? random() works fine for anything, and is part of the POSIX specification so you're going to be able to use it on pretty much any platform you like (and I'd argue that any platform that isn't POSIX-compliant is one I don't like. :D ).
 

jon3543

macrumors 6502a
Sep 13, 2010
608
265
I would assume that's what they meant.

I have, for the time being, decided to just use it and, to ensure "fairness" to the best of my ability, I include something like:

Code:
unsigned char n = (from user input);
int maxFairRand = (MAX_RAND / n) * n;
int rand = random();
while (rand > maxFairRand)
    rand = random();
unsigned char r = rand % n

As much as I can control it, this ensures that lower numbers won't be more common than higher numbers. (All of my numbers are 255 or lower... Thus why r and n are both unsigned chars.)

I'm just doing a school homework assignment that involved an RNG as a portion of it. I figure overdoing an assignment is always fun, so I tried that here.

I see that you're trying to account for the bias inherent in trying to alter the range of rand(), but there are a couple of mistakes in it. See the C FAQ for a correct approach:

http://c-faq.com/lib/randrange.html

As for the code you presented, I don't recognize random() and MAX_RAND. For Standard C, I know about rand() and RAND_MAX, which are in <stdlib.h>. Since you asked about C++ in your original question, I gave you a C++ answer in my earlier reply:

Several are part of the C++ Standard and should come with any compiler that has kept up over the last few years. Have you looked for:

#include <random>

Your other requirements are either easy to deal with or impossible to achieve using ordinary equipment.

In case it isn't clear, the Standard C++ <random> library is not remotely the same thing as C's far more primitive and less capable rand() function.

ETA: As you say you're doing homework and like to overdo things, do you understand why the C FAQ code I linked to uses unsigned int and the constant 1u in the statement, "unsigned int x = (RAND_MAX + 1u) / N;" Hint: It could have achieved the same thing with ((unsigned int) RAND_MAX+1)/N. One or the other is necessary!
 
Last edited:

ArtOfWarfare

macrumors G3
Original poster
Nov 26, 2007
9,544
6,042
In case it isn't clear, the Standard C++ <random> library is not remotely the same thing as C's far more primitive and less capable rand() function.

The <random> library wasn't recognized when I tried compiling the code on a computer running Windows 7.

ETA: As you say you're doing homework and like to overdo things, do you understand why the C FAQ code I linked to uses unsigned int and the constant 1u in the statement, "unsigned int x = (RAND_MAX + 1u) / N;" Hint: It could have achieved the same thing with ((unsigned int) RAND_MAX+1)/N. One or the other is necessary!

I'm guessing it's to account for zero? But no... that doesn't make sense...

Suppose RAND_MAX is 4 and I want one of 3 values.

My code, would do 4 / 3 = 1, then * 3 = 3.

Which means it could return 0, 1, 2, or 3... I see the issue here... I should discard values >= maxFairRand rather than only greater than it.

Or is that not the issue you're getting at?
 

jon3543

macrumors 6502a
Sep 13, 2010
608
265
The <random> library wasn't recognized when I tried compiling the code on a computer running Windows 7.

I'm pretty sure it was included at least as far back as Visual Studio 2010. I assume there's still a free compiler available for VS2012. In any case, just to see what's in it, google /msdn random vc++/. The 2nd hit I get is:

http://msdn.microsoft.com/en-us/library/bb982398.aspx

The dropdown "Other Versions" says it was in VS2008.

I'm guessing it's to account for zero? But no... that doesn't make sense...

Suppose RAND_MAX is 4 and I want one of 3 values.

My code, would do 4 / 3 = 1, then * 3 = 3.

Which means it could return 0, 1, 2, or 3... I see the issue here... I should discard values >= maxFairRand rather than only greater than it.

Or is that not the issue you're getting at?

That, plus the need to add 1 to RAND_MAX to accurately capture the number of possible values rand() can return, which goes from 0 to RAND_MAX, inclusive. Off-by-one errors lurk everywhere.

The question I posed in my "ETA" concerns some lower-level behavior, which is still very important to understand. If you get it, great; if not, post something.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.