C Programming - Beginner to Brilliance / Math & Algorithm Support

Random Number Generation

🧠 Why Random Numbers in C?

Random numbers are commonly used in:

  • Games (dice rolls, card shuffles)

  • Simulations (weather, particles, traffic)

  • Security (OTP generation)

  • Testing (fuzzing, randomized test cases)

But here’s the twist:

⚠️ C doesn’t generate “true” random numbers — it generates pseudo-random numbers using a deterministic algorithm.


🛠️ Key Functions

1️⃣ rand()

  • Generates a pseudo-random number between 0 and RAND_MAX

  • Declared in:

    #include <stdlib.h>
  • RAND_MAX is a constant defined in stdlib.h, typically 32767.

🔧 Syntax:

int rand(void);

🔁 Example:

int r = rand();
printf("Random number: %d\\n", r);  // → Could be 15431

2️⃣ srand(unsigned int seed)

In C, random numbers are generated using the rand() function. But by default, rand() generates the same sequence of numbers every time you run the program unless you "seed" it using srand().

🧠 What does srand() do?

  • srand() sets the starting point (seed) for rand().

  • If you give the same seed, you'll get the same sequence of random numbers.

  • If you change the seed (e.g. using current time), you'll get different results each time.

🔤 Syntax

void srand(unsigned int seed);

🎯 Why use it?

To make random numbers actually random across multiple runs. Useful in games, simulations, randomized testing, etc.


✅ Example : Without srand() (same output every time)

#include <stdio.h>
#include <stdlib.h>

int main() {
    for (int i = 0; i < 5; i++) {
        printf("%d\\n", rand());
    }
    return 0;
}
1804289383
846930886
1681692777
1714636915
1957747793

⏩ Running again? Same result every time.


✅ Example: With srand(10) (seeded with a constant)

#include <stdio.h>
#include <stdlib.h>

int main() {
    srand(10);  // Fixed seed
    for (int i = 0; i < 5; i++) {
        printf("%d\\n", rand());
    }
    return 0;
}
1479280589
1216767454
920368021
130027458
286331153

🧠 Same output every time you use seed = 10.


✅ Example : With srand(time(NULL)) (true randomness)

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(NULL));  // Use current time as seed
    for (int i = 0; i < 5; i++) {
        printf("%d\\n", rand());
    }
    return 0;
}
719885386
1449406407
117337446
179943811
1342001914

🎯 Generating Random Numbers in a Range

🎯 From 0 to N-1:

rand() % N

🎯 From A to B:

rand() % (B - A + 1) + A

🎲 Example: Random number between 1 and 6 (dice roll):

int dice = rand() % 6 + 1;

🧑‍🏫 Full Example: Dice Simulation

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(NULL));  // Seed only once

    for (int i = 0; i < 10; i++) {
        int dice = rand() % 6 + 1;
        printf("Dice roll %d: %d\\n", i+1, dice);
    }

    return 0;
}
Dice roll 1: 4
Dice roll 2: 1
Dice roll 3: 6
Dice roll 4: 3
Dice roll 5: 5
Dice roll 6: 2
Dice roll 7: 6
Dice roll 8: 1
Dice roll 9: 4
Dice roll 10: 2

🧠 Behind the Scenes: How Does rand() Work?

  • rand() uses a Linear Congruential Generator (LCG):

    Xₙ₊₁ = (a * Xₙ + c) % m

    where:

    • X = sequence of pseudo-random numbers

    • a, c, and m = carefully chosen constants

    • X₀ = initial seed (from srand())

So: if the seed is the same, the entire sequence is the same!


❗ Limitations of rand()

Limitation

Description

🔁 Repeats

Limited period; eventually the same numbers will repeat

🔒 Not Secure

Should not be used for cryptographic applications

🧮 Biased

rand() % n can introduce bias if RAND_MAX isn’t divisible by n


✅ Better Alternatives

In real applications (especially in C++ or cryptography), better PRNGs are available:

  • Mersenne Twister (<random> in C++)

  • /dev/urandom on Unix

  • OpenSSL or libsodium for secure RNG