11

There's a lot of conflicting information about this topic. So let's try to agree on a definitive answer:

Which one of these random number generator in C create better randomness: rand, random or arc4random?

note: Just to make the question clear, this is not a question about true randomness, it's only a clash between those 3.


As pointed out, this question doesn't make much sense, as this is not about C, but about a specific implementation, in my case, cocoa (more specifically the iphone sdk, but my guess is they are the same as far as these functions go). Still, there's some useful information here. I concluded by implementing arc4random, mostly because of its ease of use (no seeding needed), which is an important factor that no one pointed out.

I'm closing the question, and adding the cocoa tag for cocoa developers looking for information on RNGs. Many thanks for those who contributed, and sorry for the confusion.

Steph Thirion
  • 9,313
  • 9
  • 50
  • 58
  • What about the drand48() family of PRNGs? My assessment would be 'not in Standard C', part of POSIX / SUS; usually better than rand; probably not as good as random() and its supporting functions. – Jonathan Leffler Nov 30 '08 at 16:07
  • The question doesn't make sense. Only rand() is part of the C language, and the standard say nothing about how random it should be or how it should be implemented. – jalf Nov 30 '08 at 19:10
  • Yep, clearly I messed up. It should have been scoped down to cocoa. So what now? Changing the scope of the question would render the answers awkward. But there's useful information here for cocoa developers, and closing the question would send it all to limbo. What to do? – Steph Thirion Nov 30 '08 at 20:22

2 Answers2

24

Of these functions, only rand is part of standard C. random is part of POSIX, and arc4random is only provided in BSD (and derived). So only rand is "in C".

For rand, the C standard says nothing about the quality of the generator, i.e. returning always the same number would be conforming. It says that the number must be between 0 and RAND_MAX. The value of RAND_MAX, and the precise algorithm being used, are implementation defined (although RAND_MAX must be at least 32767).

For random, POSIX specifies that it must have a period of atleast 2^31 by default, and, if initstate is called with 256 bytes of state, then it must have a period of atleast 2^69; other details are again implementation-defined.

For arc4random, the specific implementation is part of its definition (RC4). It's specified that it gives 2^32 different values; I could not find anything about its period.

To compare them in detail, one would have to know what specific implementation you refer to.

Martin v. Löwis
  • 124,830
  • 17
  • 198
  • 235
  • hi martin, in my case the implementation is the iphone SDK. Is it really important for this question? Should I edit? I'd be better if I could avoid changing the scope of the question. – Steph Thirion Nov 30 '08 at 16:06
  • If the iphone SDK is similar to OSX, then the rand() implementation is from FreeBSD (rand.c 1.15). The algorithm then is from Parker and Miller, "Random number generators: good ones are hard to find". random then uses the very same algorithm if initstate's n is < 8; rand already is a good algorithm – Martin v. Löwis Nov 30 '08 at 17:16
  • Is the arc4random algorithm the same in all implementations? I read here it's the best in cocoa: http://iphonedevelopment.blogspot.com/2008/10/random-thoughts-rand-vs-arc4random.html . How does it compare in general with the other 2, in most implementations? Maybe we can reach some consensus. – Steph Thirion Nov 30 '08 at 20:27
  • I think the blog article is misguided. It claims that because arc4random produces 32bits instead of 31, it gives "much more precision" - but actually, it only gives one additional bit. In a typical application, you don't even need 31 bits per call, but much less. Both rand and arc4random are decent. – Martin v. Löwis Nov 30 '08 at 20:49
  • @StephThirion @Martinv.Löwis I think it's worth noting at this point that Apple's man page for [`rand(3)`](https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/rand.3.html) opens by outright obsoleting `rand` in favor of `arc4random`. And the man page for [`random(3)`](https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/random.3.html) concludes that applications in need of cryptographically secure randomness should use `arc4random` instead. – justinpawela Aug 11 '15 at 18:59
  • @user2194039: I think it's worth noting that Mantin and Shamir have proven that there is a [fairly reliable test](http://saluc.engr.uconn.edu/refs/stream_cipher/mantin01attackRC4.pdf) to detect RC4 as non-random. So the quality of RC4 for cryptographically random number generation has been challenged since 2001. – Martin v. Löwis Sep 08 '15 at 22:14
  • In this specific case, RC4 being challenged seems irrelevant. The question was with regards to iOS, and the iOS documentation warns against using `rand` and `random` and recommends ARC4. If Apple is saying "`arc4random` is our best", it hardly seems wise to go with their less-than-best just because RC4 has been challenged. Certainly some other option would be ideal, but it's not offered, and it's not relevant in the context of this question anyway. In any case, my remark was meant as informational for anyone who found themselves here (like myself), not a personal attack on your answer. – justinpawela Sep 08 '15 at 22:49
9

The implementation of rand() is not specified by the C standard, however most compilers use a linear congruential generator. random() and arc4random() aren't standard C either, but they are better than the usual implementation of rand()

I'd say: arc4random() is better than random() is better than rand()

rand() is really terrible. You could easily do better than all three however.

It also depends what you want the random numbers for. A good random number generator for encryption/security may not be a good random number generator for simulation and vice-versa.

Roland Rabien
  • 8,750
  • 7
  • 50
  • 67