Skip to main content

Building a Password Generator in Python with Provable Entropy

Password Security Series · Part 4 of 5

Building a Password Generator in Python with Provable Entropy

In the earlier posts, we counted a structured generator, discussed closed-form entropy, and measured password spaces in Python. Now we combine those ideas into a real implementation: a generator that is readable, policy-friendly, cryptographically random, and still mathematically analyzable.

Password Series

Goal

Build a real generator without losing the ability to measure its entropy exactly.

Randomness source

Use Python’s secrets module for cryptographically secure randomness.

Result

This design produces about 69 bits of entropy in a readable format.

The implementation standard A production-grade password generator should not just look secure. Its randomness source, output format, and mathematical search space should all line up.
Design goals

What we want from the generator

Our goal is to build a password generator that is:

  • Human-readable
  • Easier to remember than a fully arbitrary character string
  • Compatible with common enterprise password policies
  • Based on cryptographically secure randomness
  • Backed by mathematically provable entropy

That combination is what makes the design interesting. We are trying to balance usability and analysis, not just maximize visual complexity.

The format

Password structure

We will generate passwords using this structure:

segment-segment-segment

Each segment follows these rules:

  • Each segment contains 3–5 lowercase letters
  • The three segment letter-lengths must all be different
  • Exactly one segment contains a digit
  • Exactly one segment contains a symbol
  • The digit and symbol cannot appear in the same segment
  • Digits and symbols appear only as prefixes or suffixes
The math

Password space and entropy

From the earlier analysis, the total number of passwords is:

\[ 5760 \cdot 26^{12} \]

That gives a total space of approximately:

\[ 5.50 \times 10^{20} \]

Entropy is therefore:

\[ H = \log_2(5760 \cdot 26^{12}) \approx 68.9 \]

So this generator provides roughly 69 bits of entropy.

Why this is useful That number is not a guess. It comes directly from the structure of the generator.
Secure randomness

Why secrets matters

Python’s secrets module is designed for security-sensitive randomness such as password generation.

import secrets
import string

This matters because the standard random module is not designed for password generation. A mathematically strong output format still needs a cryptographically strong random source.

Implementation

Password generator in Python

import secrets
import string

def generate_password():
    letters = string.ascii_lowercase
    digits = string.digits
    symbols = "!@#$%^&*"

    lengths = [3, 4, 5]
    secrets.SystemRandom().shuffle(lengths)

    number_segment = secrets.randbelow(3)
    symbol_segment = (number_segment + secrets.randbelow(2) + 1) % 3

    segments = []

    for i, length in enumerate(lengths):
        core = "".join(secrets.choice(letters) for _ in range(length))

        if i == number_segment:
            digit = secrets.choice(digits)
            if secrets.randbelow(2):
                core = digit + core
            else:
                core = core + digit

        elif i == symbol_segment:
            sym = secrets.choice(symbols)
            if secrets.randbelow(2):
                core = sym + core
            else:
                core = core + sym

        segments.append(core)

    return "-".join(segments)
Example outputs

Sample passwords

Examples that match the stated structure:

7abc-defg-hijkl!
abc$-defg9-hijkl
abc4-!defg-hijkl
abcz-7defg-hijkl@
abc#-defg-hijkl5

These examples are not special because they “look complex.” They are useful because they visibly follow the same model we analyzed mathematically.

Why this design works

What the generator gets right

  • High entropy from a countable combinatorial structure
  • Cryptographic randomness from secrets
  • A readable multi-segment format
  • Compatibility with systems that expect a digit and symbol

This makes the design suitable for environments where both usability and strong temporary-password generation matter.

Enterprise relevance

Why provable entropy matters in provisioning workflows

In enterprise identity systems, password generators often appear inside onboarding and account-provisioning workflows.

A script might:

  • Create a user via API
  • Generate a temporary password
  • Assign the user to a group
  • Require a password change at first login

In that context, “this password comes from a generator with a measured search space” is a much better property than “this password happens to satisfy a complexity checklist.”

FAQ

Frequently Asked Questions

These are the practical questions that usually come up when building a password generator whose implementation matches a measurable entropy model.

Why use secrets instead of random for password generation?

Because secrets is designed for security-sensitive randomness. A strong password format still depends on a strong random source underneath it.

Why does this generator count as “provable” entropy?

Because the structure is explicit enough to count exactly. Once the number of valid outputs is known, entropy follows directly from \(\log_2(N)\).

Does readability automatically reduce security?

Not necessarily. Structure reduces freedom, but the remaining space can still be large. The important question is how big the counted search space still is after the constraints are applied.

Why keep the digit and symbol in different segments?

That rule is part of the design model. It preserves readability, keeps the structure analyzable, and is already accounted for in the entropy calculation.

Can I change the symbol set or segment rules later?

Yes, but changing the structure changes the password space. Once the rules change, the entropy analysis needs to be recomputed from the new model.

Why is this especially useful for enterprise onboarding?

Because temporary-password workflows benefit from generators that are both policy-friendly and measurable. It is much stronger to say the generator has a defined search space than to rely only on generic complexity rules.

Conclusion

A good password generator is not just an implementation detail. It is a mathematical object expressed in code.

By combining combinatorics, entropy analysis, and cryptographically secure randomness, we can build generators that are both practical and measurable.

That gives us a much stronger position from which to evaluate traditional password policies — which is exactly where the final post in this series goes next.

Series navigation

Previous: Measuring Password Entropy with Python

Next in the series: Why Most Password Complexity Rules Fail Mathematically

Raell Dottin

Comments