Technical

Generate every Gmail dot alias in Python (itertools)

Gmail ignores dots in the part before the @. That means johnsmith@gmail.com, john.smith@gmail.com and j.o.h.n.smith@gmail.com all land in the same inbox — they are the same account to Google, just written differently.

That quirk is genuinely useful:

  • Give a different dotted version of your address to each service, then filter incoming mail by the exact address it was sent to.
  • When spam arrives, the dotted form it was sent to tells you which service leaked or sold your address.
  • Testing a sign-up flow that needs several “different” emails that all reach one inbox.

This post works out how many dotted variants an address has and generates them all in a few lines of Python.

How many aliases are there?

For a username of n characters there are n − 1 gaps between the letters. Each gap either has a dot or it doesn’t — two choices per gap — so there are 2(n−1) combinations in total, including the plain address with no dots. Excluding the original, that leaves 2(n−1) − 1 extra aliases.

  • n = 3 → 22 = 4 forms (3 aliases + the original)
  • n = 4 → 23 = 8 forms (7 aliases)
  • n = 5 → 24 = 16 forms (15 aliases)

(The growth is exponential, so a 20-character username has over a million forms — you rarely want them all.)

The idea: dots are a binary string

Each gap is a yes/no choice, so the whole pattern of dots is just a binary string of length n − 1. For abc the four patterns are 00 → abc, 01 → ab.c, 10 → a.bc, 11 → a.b.c. Python’s itertools.product enumerates every such pattern for us.

The code

from itertools import product

def gmail_dot_aliases(username, domain="gmail.com"):
    """Yield every dot-variant of a Gmail username, including the original."""
    gaps = len(username) - 1
    for bits in product((False, True), repeat=gaps):
        out = username[0]
        for char, dot in zip(username[1:], bits):
            out += ("." if dot else "") + char
        yield f"{out}@{domain}"

for alias in gmail_dot_aliases("johnsmith"):
    print(alias)

product((False, True), repeat=gaps) walks through all 2(n−1) on/off patterns; for each one we rebuild the username, inserting a dot wherever the bit is set. The first character never gets a leading dot, which is why we start from username[0] and iterate over the rest.

A couple of caveats

  • The dots-are-ignored rule is specific to @gmail.com. Google Workspace accounts on a custom domain can be configured differently, so don’t assume it there.
  • Gmail also ignores anything after a + (johnsmith+shopping@gmail.com), which is often simpler than dots for per-service tagging.
  • Use this for organizing your own mail — not for creating fake “separate” accounts to abuse free trials or sign-up limits.

Nguyen

I write two things here: notes from a homelab that mostly runs Proxmox, and essays in Vietnamese about a country I left. The technical posts are whatever broke that week, written down so it costs you less time than it cost me.

All posts →

Leave a comment

Comments are reviewed before they appear. Your email is never published.