Logo
Logo
Home
Archive
AI Agent Notes
Advertise
YouTube
Login
Sign Up
Logo
  • Home
  • Posts
  • 🦄 Random isn’t ā€œRandomā€

🦄 Random isn’t ā€œRandomā€

Sep 30, 2025

In partnership with

Hello friends!

Welcome to this week’s Sloth Bytes. I hope you had a great week.

Dex AI Scrapes the internet and sets up interviews for you

Dex is a conversational AI and career matchmaker that works on behalf of each person. You spend 15-20 minutes on the phone with him, talking about your experience, your ambitions and your non-negotiables.

Dex then scans thousands of roles and companies to identify the most interesting and compatible opportunities.

Once we’ve found a match, Dex connects you to hiring managers and even helps you prep for interviews.

Thousands of exceptional engineers have already signed up and we’re partnered with many of the UK’s leading Start-ups, Scale-ups, hedge funds and tech companies.

Don’t waste another day at a job you hate. Speak with Dex today.

Get Started

Go from AI overwhelmed to AI savvy professional

AI will eliminate 300 million jobs in the next 5 years.

Yours doesn't have to be one of them.

Here's how to future-proof your career:

  • Join the Superhuman AI newsletter - read by 1M+ professionals

  • Learn AI skills in 3 mins a day

  • Become the AI expert on your team

Start learning AI now

Why Random isn’t ā€œRandomā€

A few years ago, I was in a final-round technical interview.

Fun little zoom call. Multiple interviewers. My hands were sweating like crazy.

After finishing all the normal interview problems we had some extra time.

So they asked me a fun bonus question:

ā

ā€œHow would you write a program to randomly shuffle a deck of cards?ā€

Easy enough, right? I asked if I can use the random package and they said sure.

Now in my head I thought ā€œWow this is way easier than the other questions.ā€

The solution basically looks like this with the random package.

#Simplified version - shuffling numbers in an array
import random
deck = [1,2,3,4]
#Yep the random package has a shuffle method.
random.shuffle(deck)

Boom. Done.

At this point I felt pretty confident, but then one interviewer hit me with this question:

ā

ā€œHow do you know if that package is truly shuffling them random?ā€

And that’s where I froze. Because I had no idea.

Is random actually random?

Well… Software Usually Uses Pseudorandomness

Ordinary software is deterministic: given the same internal state and inputs, it follows the same rules. So most general-purpose ā€œrandomā€ APIs generate pseudorandom values with algorithms rather than inventing entropy from nothing.

But computers can also collect nondeterministic physical/environmental signals through hardware and operating-system entropy sources. Modern secure randomness usually combines that entropy with a cryptographically secure pseudorandom generator.

So the useful distinction isn’t ā€œcomputers can never do true random.ā€ It’s: normal PRNGs are deterministic and reproducible; security-sensitive generators are designed to be unpredictable and are seeded/reseeded from high-quality entropy.

For simulations, games, tests, and shuffling where adversaries are not involved, a normal PRNG is often exactly what you want.

For passwords, tokens, keys, and cryptography, use the operating system’s secure randomness APIs or a library built on top of them.

What is the computer doing then?

When you ask your computer for randomness, it doesn’t pull chaos out of thin air. Instead, it uses a pseudorandom number generator (PRNG).

A PRNG is an algorithm that produces a sequence that looks random. If you know enough about its algorithm and internal state—including its seed/state—you may be able to reproduce or predict the sequence. That reproducibility is a feature for simulations and testing, but a disaster for secrets.

PRNGs in simple terms

PRNGs usually consist of two parts:

  1. The seed

  2. A math algorithm that spits out numbers.

The seed is the starting point and the math algorithm uses that seed to generate a sequence of numbers.

If you’re curious here’s a list of PRNGs

Why do we need a seed?

To reproduce the ā€œrandomā€ result. Weird, I know.

  • Same seed + same PRNG algorithm/implementation/state rules → the same pseudorandom sequence.

  • Different seed → usually a different sequence.

Example you can try

import random

random.seed(42)  
print([random.randint(1, 10) for _ in range(5)])

The output you should get is [2, 1, 5, 4, 4].

With the same Python version/compatible random implementation and seed, you should reproduce the same sequence. Don’t treat a seeded stream as a cross-language or forever-across-versions serialization format unless the library explicitly guarantees that behavior.

Why is this useful?

Because reproducibility matters:

  • In ML experiments, you want the same ā€œrandom splitā€ of data.

  • In debugging, you want to replay the same test run.

  • In games, you want to recreate the same world from a seed (Minecraft)

So ā€œrandomā€ in this case isn’t true randomness. It’s just math following rules.

Where Do Seeds Come From?

Okay, so if PRNGs need seeds, where do those come from?

How a generator gets initialized depends on the language/library. Non-cryptographic PRNGs may use an explicit seed for reproducibility or automatically initialize themselves. Secure randomness APIs typically draw seed material from the operating system’s entropy facilities, which aggregate unpredictable system and hardware events.

  • An explicit developer-provided seed (useful for reproducible tests/simulations)

  • Operating-system randomness such as getrandom(), /dev/urandom, or platform equivalents

  • Entropy gathered by the OS from hardware and system events

Once a deterministic PRNG has a particular internal state, its future sequence is determined. The security question is whether an attacker can feasibly learn or predict that state.

ā™ ļø Back to the Deck Shuffle

Now we only covered how the ā€œrandomā€ part works, but how does the shuffle work?

A common way to implement an unbiased in-place shuffle is the Fisher–Yates shuffle. Python’s random.shuffle() uses a well-designed shuffle routine, but the important idea is broader than one language: each step must choose uniformly from the remaining valid positions.

Here’s the implementation in Python (thanks wikipedia):

def shuffle(numbers: list[int]) -> list[int]:
    for i in range(len(numbers) - 1, 0, -1):
        #IMPORTANT PART!
        j = random.randint(0, i)
        numbers[i], numbers[j] = numbers[j], numbers[i]
    return numbers

You see that random.randint(0, i)?

That is what’s making this implementation possible.

The shuffle is only unbiased if those index choices are uniform. A correct Fisher–Yates algorithm paired with a biased range-mapping method can still produce a biased deck. Good standard-library integer APIs avoid common mistakes such as naive modulo reduction when the source range is not evenly divisible by the target range.

And if an attacker needs to be unable to predict the shuffle—think online gambling, lotteries, secret assignments, or security protocols—the randomness source must also be cryptographically secure. Python’s normal random module is explicitly for simulation/general-purpose randomness, not secrets.

And that means it’s not that ā€œrandom.ā€

šŸ” Crypto-Grade Randomness

WAIT A MINUTE… If patterns can exist, doesn’t that mean encryptions and random password generators are not that secure?

Couldn’t attackers could guess the seed and reproduce the sequence.

Yes—if you use a predictable non-cryptographic generator for secrets, an attacker who recovers or infers its state may be able to predict future values.

But don’t worry, modern systems provide cryptographically secure PRNGs (CSPRNGs).

CSPRNGs are designed so that, assuming their secret internal state remains unknown and the implementation is sound, observing previous outputs does not make future outputs feasibly predictable. Operating systems seed and reseed these generators from entropy sources.

Example

# Python's secure randomness
import secrets
print(secrets.token_hex(16))

For a security-sensitive shuffle in Python, use a secure generator such as random.SystemRandom(), which draws from the operating system rather than the deterministic Mersenne Twister used by the normal random module:

import random

secure_random = random.SystemRandom()
deck = list(range(52))
secure_random.shuffle(deck)

These are what you’d use for things like password-reset tokens, API keys, session identifiers, cryptographic keys, and other security-sensitive values.

Knowing the algorithm is not supposed to be enough to predict the sequence; security comes from the generator’s unknown internal state and high-quality entropy, not from hiding how the algorithm works.

Fun fact: Cloudflare uses a wall of lava lamps as one additional physical entropy source.

Cameras capture unpredictable visual patterns, and that data contributes entropy to Cloudflare’s randomness systems. The lamps do not directly encrypt TLS traffic; they are one additional entropy source feeding systems that need unpredictable random values.

Cloudflare’s lava lamps contribute physical entropy; they are not tiny glowing TLS servers.

Takeaway

That interviewer asked a really good question. I don’t know if this was the answer they were looking for, but still a good question.

If I could go back to that interview, I’d probably say something like this:

ā

ā€œPython’s random module uses a deterministic pseudorandom generator, so it’s great for ordinary shuffling but not for security. A proper shuffle algorithm like Fisher–Yates can be unbiased if each random choice is uniform. If the shuffle were security-sensitive, I’d use a cryptographically secure randomness source such as Python’s secrets or the OS CSPRNG.ā€

What a mouthful of an answer

If I said that, I probably would’ve gotten the job…

But hey, maybe it’ll help you with one.

If you want to keep learning

  • How passwords actually work — secure password systems rely on random salts and security-focused hashing rather than predictable values.

  • How two-factor codes work — authentication apps depend on secret keys that need to be generated and protected securely.

  • How environment variables and secrets leak — generating a secure key is only half the battle; you also have to keep it out of Git, logs, and frontend builds.

Every Cloudflare feature, available to everyone

Cloudflare is making every feature available to any customer.

Visual Studio 2026 Insiders is here! - Visual Studio Blog

Visual Studio 2026 Insiders is here with AI integration, blazing fast performance, Fluent UI design, and a new Insiders Channel for early features.

TanStack Start v1 Release Candidate | TanStack Blog

TanStack Start has officially reached a v1.0 Release Candidate. This is the build we expect to ship as 1.0, pending your final feedback, docs polish, and a few last-mile fixes. Now’s the perfect time...

Haydex: From Zero to 178,600,000,000 rows a second in 30 days

This is the story of how we turned a failed filter prototype into a production system running at 178.6B rows/sec in 30 days.

Why you should replace PostgreSQL with Git for your next project

Explore how Git's internal architecture makes it a surprisingly capable database alternative.

Thanks to everyone who submitted!

grcc492, Melvis-07, Yeshua235 , AspenTheRoyal, gcavelier (used a crate/package to handle it. Practical. I respect it), jsjasee, NeoScripter, and Suji-droid!

A lot of you solved it with dfs and bfs great job!

Keyword Cipher

A Keyword Cipher replaces each letter of a message with a letter from a shifted alphabet built using a keyword.

  1. Start with the keyword.

  2. Add the remaining letters of the alphabet (A–Z) in order, skipping any that already appeared in the keyword.

    • Example keyword: "KEYWORD"

    • Cipher alphabet: KEYWORDABCFGHIJLMNPQSTUVXZ

  3. Encrypt by replacing each letter in the message with the letter at the same position in the cipher alphabet.

    • Plain alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ

    • Cipher alphabet: KEYWORDABCFGHIJLMNPQSTUVXZ

Write a function that takes a key and a message, and returns the encrypted message.

Examples

keyword_cipher("keyword", "abchij")
Output = "keyabc"

keyword_cipher("purplepineapple", "abc")
output = "pur"

keyword_cipher("mubashir", "edabit")
output = "samucq"

keyword_cipher("etaoinshrdlucmfwypvbgkjqxz", "abc")
Output = "eta"

keyword_cipher("etaoinshrdlucmfwypvbgkjqxz", "xyz")
Output = "qxz"

keyword_cipher("etaoinshrdlucmfwypvbgkjqxz", "aeiou")
Output = "eirfg"

How To Submit Answers

Reply with

  • A link to your solution (github, twitter, personal blog, portfolio, replit, etc)

  • or if you’re on the web version leave a comment!

  • If you want to be mentioned here, I’d prefer if you sent a GitHub link or Replit!

That’s all from me!

Have a great week, be safe, make good choices, and have fun coding.

If I made a mistake or you have any questions, feel free to comment below or reply to the email!

See you all next week.

What'd you think of today's email?

  • 🦄 Amazing! Keep it up
  • 🦄 Good, not great
  • 🦄 It sucked

Login or Subscribe to participate

Want to advertise in Sloth Bytes?

If your company is interested in reaching an audience of developers and programming enthusiasts, you may want to advertise with us here.

Keep Reading

Read all
arrow-right
envelope-simple

Join 50k+ developers and become a better programmer and stay up to date in just 5 minutes.

Ā© 2026 Sloth Bytes.
beehiivPowered by beehiiv