0

I'm currenlty studying PRNG, and I found that there are two function, rand() and random(), in GNU/Linux. According to the GNU C Library section 19.8.2, this function, random(), is just for supporting BSD compatibility. Here are my questions:

  1. Are these two functions identical?
  2. If so, where is the source code of random()? (I can only find rand() in glibc)

I've tried to fix the seed parameter, and the order of the random number from rand() and random() are the same in my PC. So, I started to find where rand() and random() are implemented in glibc. Eventually, I can only found the implementation of rand(), and the prototype of random() in stdlib/stdlib.h (this is not official mirror).

I also try to find it in the linux source code, but still, there is no implementation of random(). Is there anything I missed?

Edit1:

(Source code of random() prototype)

/* These are the functions that actually do things.  The `random', `srandom',
   `initstate' and `setstate' functions are those from BSD Unices.
   The `rand' and `srand' functions are required by the ANSI standard.
   We provide both interfaces to the same random number generator.  */
/* Return a random long integer between 0 and RAND_MAX inclusive.  */
extern long int random (void) __THROW;

Answer:
Yes, they're identically the same in glibc. The reason why they are the same is because weak_alias (__random, random) in random.c, which eventually use the GNU C extension called alias.

ranvd
  • 13
  • 2
  • I’m voting to close this question because it requires two clicks to find the source in the OP provided link https://github.com/lattera/glibc/blob/master/stdlib/random.c – 0___________ Jul 11 '23 at 15:20
  • Should I paste the source code in this post? If this is need I can paste it. – ranvd Jul 11 '23 at 15:26
  • 1
    What is the question then? – 0___________ Jul 11 '23 at 15:37
  • 1
    @0___________ Reading glibc source code is no trivial thing, so a proper answer for the less gifted coders among us (like myself) would be highly appreciated. Thanks in advance. – Ruud Helderman Jul 11 '23 at 15:41
  • @RuudHelderman But I do not see any questions! The source of random is in my comment. I do not see more questions here. – 0___________ Jul 11 '23 at 15:43
  • I want to find the source code of `random()` in glibc to check if `rand()` and `random()` are really identical as I expect. – ranvd Jul 11 '23 at 15:49
  • 3
    Maybe the more interesting source is [rand.c](https://github.com/lattera/glibc/blob/master/stdlib/rand.c): `int rand(void) { return (int) __random(); }` – together with `weak_alias (__random, random)` from the other file the issue should be clear, shouldn't it? – Aconcagua Jul 11 '23 at 15:50
  • but the source code you provide in the link is __random. Can it equal to random? I can only see it been call in `rand()` [source code](https://github.com/lattera/glibc/blob/master/stdlib/rand.c) – ranvd Jul 11 '23 at 15:52
  • Ah, you might yet be interested in the [weak alias](https://stackoverflow.com/questions/34892601/what-does-the-weak-alias-function-do-and-where-is-it-defined)! Basically they *are* the same, though the weak alias would allow for exchanging `random` with another implementation while the same for `rand` does not apply (in short here: `random` is just an alias for `__random`). – Aconcagua Jul 11 '23 at 15:55
  • Thank you so much, this is out of my knowledge. I really appreciate it. – ranvd Jul 11 '23 at 15:58

2 Answers2

0

They are currently the same in glibc. However, you should use random() and not rand(). The reason is that historically the implementation of rand() was not the same and was an extremely poor random number generator. From cppreference:

There are no guarantees as to the quality of the random sequence produced. In the past, some implementations of rand() have had serious shortcomings in the randomness, distribution and period of the sequence produced (in one well-known example, the low-order bit simply alternated between 1 and 0 between calls).

Depending on what you are compiling on, you could end up with an old, low-quality rand(). It's a crap shoot, so don't use it.

The one drawback is that random() is a POSIX function, not a standard C function. You will generally find random() everywhere, except on Windows Visual C. There you should use rand_s() instead of rand().

For something truly portable and consistent, you could avoid libraries entirely and include the random number generator in your code. The PCG family of generators provide very high-quality random numbers, better than even some modern library generators, and with very fast and compact code.

The C++ standard defines and requires high-quality random number generators, found in #include <random>. In C++, those are a very good choice for both portability and quality.

Depending on your application, most of these have issues. See https://www.pcg-random.org/other-rngs.html . Also consider how a pseudo-random generator is seeded. Most operating systems provide truly-random data that can be used for that.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • You shouldn't use _either_; they are both inadequate to modern standards for (pseudo)randomness. (They cannot be updated to newer algorithms because that would change the meaning of stored seed values.) – zwol Jul 12 '23 at 00:22
0

Are these two functions identical?

not necessarily. rand() and random() historically come from different sources and so, they implement unrelated code. But it is normal that a library that implements both, uses the same algorithm as a common code.

If so, where is the source code of random()? (I can only find rand() in glibc)

Probably it can be also there. Check the header files for a macro definition.

Anyway, the specifications of both are different, so check the manual page as they will probably give different random sequences for the same seeds.

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31