← Back to Gists

How to Generate Unique, Realistic Usernames for a Forum

📝 Markdown Rendered
retoor
retoor · Level 54922 ·

Accounts often have to be created for people who never picked a handle: bulk imports, migrations, data feeds. The source rarely carries a clean name. You get strings like abner_page_by_abnercoimbre or via_rberger_2026-10-15_12_36_38_. This article describes a method that turns such strings into names a person would actually pick, and keeps them unique and stable.

Accounts often have to be created for people who never picked a handle: bulk imports, migrations, data feeds. The source rarely carries a clean name. You get strings like abner_page_by_abnercoimbre or via_rberger_2026-10-15_12_36_38_. This article describes a method that turns such strings into names a person would actually pick, and keeps them unique and stable.

The problem

Raw author strings often have the shape <site> via <person> or <site> by <person>:

lore.kernel.org via thang
jakearchibald.com by jaffathecake
decomp.dev via FedericoSchonborn

Using that string as the username gives ugly names. Worse, it gives the same person several accounts, because the same person appears next to different sites and each string looks like a different author.

Fix the identity first, then the name.

Step 1: Decide who the person is

Before you generate anything, define the identity key, because a handle is only stable if the key is.

  • Strip noise from the raw string: timestamps (2026-10-15 12:36:38) and relation words.
  • If the string says by or via, the person is the token after it. The site comes before it.
  • If the string is only a domain (costa_jacobpalm_dk), drop the top-level domain and keep the last meaningful label (jacobpalm).
  • Use that cleaned person as the identity key, not the original string.

Now one person appearing next to ten sites is one account.

Step 2: Create the handle once and store it

Generate a handle the first time you see an identity. Store the link between the identity and the account in a table with a unique constraint, for example (source, identity) -> account.

Every later lookup finds the link and uses the stored name. The generator is never consulted twice for the same person. Renaming later is how you end up with handles that drift, so do not do it.

Two guards matter:

  • Only choose the name when the account is created. Later updates keep the stored name.
  • Never touch accounts that already exist. Backfilling old names is a separate decision with its own risks.

Step 3: Make the name look chosen

Real handles are not random strings. One empirical study of usernames on Google profiles (arXiv 1101.5578, 2011, Latin-alphabet names only) found:

  • About 70% of usernames contain part of the user's real name.
  • About 30% are plain first-plus-last concatenations.
  • More than 18% add digits to the name, likely birth years or a number to get around a taken name.

That is the only solid distribution found. It says nothing about separators or humorous suffixes, so those weights are judgment, not data.

Pick one pattern per person with fixed weights:

Pattern Weight Example
Plain name 40% runxiyu
Name plus a number (year, two-digit year, or a small number) 30% hongminhee90, untrusem_2000
Separator plus number 8% jaffathecak-73
Funny (prefix, suffix, or a nerd number) 17% federicoschonborn_irl, lcapald_500
Light leetspeak 5% wr1ter0

The funny parts come from small word lists: prefixes like its, dr, mr; suffixes like _dev, _irl, _ftw; numbers like 42, 1337, 404, 418. Years run 1972 to 2006.

Step 4: Make it deterministic

Seed the random generator from a hash of the source and the identity, for example sha256(source:identity). The same person then always produces the same ordered list of candidates, which makes the system reproducible and testable.

If the first candidate is taken, move to the next. Finally fall back to a numbered suffix, so a free name always exists.

Step 5: Enforce hard limits

Constants, not heuristics:

  • Characters: letters, digits, _ and - only.
  • Length: 3 to 32.
  • Base name: trimmed to 18 characters before decoration, so a suffix always fits.
  • Case: lowercase, as people usually type handles.
  • A bounded number of re-rolls before the fallback.

Test these with property checks across many inputs, including empty strings, very long strings, accented characters, and strings made only of separators. Every candidate must be valid.

Step 6: Handle the exceptions

  • Deliberate pseudonyms. If you replace names on purpose so the original is hidden, do not decorate those names. Mentions are rewritten to match the replacement, and any change would break the match.
  • Trusted senders. If another system sends you clean handles, keep them. Apply this method only where the names cannot be trusted.
  • Collisions. Compare names case-insensitively, since Alice and alice should not coexist.

Known weaknesses

  • The weights are constants, not tuned on real data from your own user base.
  • A name that already ends in digits can look odd after a year is added (spc476 becoming spc4762005).
  • Changing the identity key means records created before the change no longer match their old links. They appear as new accounts, and the old ones remain as orphans. Plan a cleanup if that matters.
  • The result is a plausible handle. It makes no claim about who the person is.

Summary

  1. Fix the identity first: extract the person, drop the site and the stamp.
  2. Create the handle once, store the link, and never regenerate it.
  3. Pick a pattern with weights based on how real people name themselves.
  4. Seed the randomness from the identity so results are reproducible.
  5. Enforce length, character and uniqueness rules.
  6. Leave existing accounts and deliberate pseudonyms alone.

Comments

No comments yet. Start the discussion.