Skip to Content
Course content

107: Random Number Functions: random_int, mt_rand

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you're organizing a giveaway for your community. For a low-stakes prize, like a free sticker, you might just put a bunch of names in a hat and shake it up. It's fast, it's "random enough," and if someone somehow predicted which name you'd pull, it's not the end of the world. But if you're generating a password reset token or a high-stakes lottery winner, you can't just "shake a hat." You need a process that is mathematically impossible to predict, even for someone who knows exactly how your system works.

In PHP, we map these two scenarios to two different functions: mt_rand() is our "shaking the hat" method, and random_int() is our "cryptographically secure" method.

The Fast and Loose Approach with mt_rand

When you're building something like a game where a monster has a 20% chance to drop a rare item, you don't need military-grade security. You just need something fast that feels random to the player. That's where mt_rand() comes in. It uses the Mersenne Twister algorithm, which is significantly faster and "more random" than the ancient rand() function you might see in some legacy tutorials (seriously, just ignore rand() entirely).

// Simulating a critical hit in a game
$chance = mt_rand(1, 100);

if ($chance <= 10) {
    echo "Critical hit! Massive damage!";
} else {
    echo "A regular hit.";
}

The only catch? mt_rand() is pseudo-random. If someone knows the "seed" (the starting point) and the algorithm, they can technically predict every single number that will come next. For a game, that's a minor bug; for a security feature, that's a catastrophe.

When Security is Non-Negotiable with random_int

If you're dealing with anything involving money, passwords, or user identity, you must use random_int(). Unlike its cousin, this function generates cryptographically secure pseudo-random integers. It gathers "entropy" from your operating system—basically, it looks at unpredictable system noise—to ensure the number it picks is truly unpredictable.

I always tell my junior devs: if the number you're generating is going to be sent to a user as a secret, use random_int(). No exceptions.

// Generating a 6-digit verification code for an email sign-up
try {
    $verificationCode = random_int(100000, 999999);
    echo "Your secure code is: " . $verificationCode;
} catch (\Exception $e) {
    // In very rare cases, the system might not have enough entropy
    echo "Could not generate a secure number: " . $e->getMessage();
}

Choosing Your Tool

To keep it simple, I use a quick mental checklist when deciding which one to reach for:

  • Is this for a visual effect, a game mechanic, or a non-sensitive shuffle? → mt_rand().
  • Is this for a token, a password, a session ID, or any security-related value? → random_int().

One last tip: random_int() is slightly slower than mt_rand() because it has to do more work to be secure. In 99% of your web apps, you won't even notice the difference, but it's good to know why it exists.




📋 Practical Task

Build a Secure One-Time Password (OTP) Generator

Your task is to create a script that simulates a secure account verification system. You need to build a "Verification Service" that does the following:

  • Generates a cryptographically secure 6-digit integer (between 100,000 and 999,999).
  • Stores that number in a variable.
  • Prints a message to the screen that looks like: "Security Alert: Your one-time verification code is: [number]. This code expires in 10 minutes."
  • Wraps the generation logic in a try-catch block to handle any potential Exception that random_int() might throw if the system lacks sufficient entropy.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.