Randomly

Validators

SSN format checks are not identity checks

Bipul Kumar 8 min
SSN format checks are not identity checks
On this page 0%

A Social Security Number looks like a secret. Nine digits, two hyphens, a shape every US form already knows. That familiarity is why people paste a real one into a staging database “just this once.” I built the SSN generator so I would stop doing that. The numbers it prints are format-shaped. They are not yours, not anyone’s, and not a way to impersonate a taxpayer.

This post is the structure the SSA used, what randomization in 2011 actually changed, which prefixes stay invalid on purpose, and why a checksum-free identifier is a terrible identity proof. If you only need a field that looks like AAA-GG-SSSS, generate it. If you need to know whether a person exists, that is a different product, with legal teeth I am not pretending to grow.

Diagram of an SSN split into area, group, and serial fields with hyphens
Area, group, serial. The hyphens are for humans. The invalid prefixes are for everyone.

The old area, group, serial story

Before June 2011, the first three digits (the area number) were assigned by geography. Not a GPS pin. A rough map of where the card was issued, which often tracked the mailing address on the application. Low numbers clustered in the northeast. High numbers showed up farther west. People wrote folklore about reading a life from a prefix. Some of that folklore was directionally true for older cards. None of it was a background check.

The middle two digits are the group number. They were not “a family code.” SSA issued groups in a weird order (odds, then evens, in a sequence you can look up if you enjoy government PDFs). The last four are the serial. Within an area and group, serials ran 0001 through 9999. Serial 0000 was not used. That last fact still matters for format checks.

I used to think “area number” meant the person still lived there. It never did. People move. Treating the prefix as a current ZIP is a bad heuristic. Group-number regexes from 2004 blogs go stale. A validator that encodes a dead issuance table will reject valid numbers and accept junk that matches the souvenir chart.

Randomization in 2011

SSA started randomizing SSNs on June 25, 2011. The point was to stretch the remaining number space and to stop the geography leak. New area numbers are not a map. You cannot infer a state from a 2012 issuance the way a hobbyist could from a 1978 one. Any “SSN decoder” site that still sells state lookup for fresh numbers is selling nostalgia.

Randomization did not make every nine-digit string legal. SSA kept some area numbers out of circulation. 000 is invalid. 666 is invalid. Area numbers 900 through 999 are not SSNs in the usual sense; some of that range shows up in ITIN-adjacent and other tax-processing contexts, which is exactly why you should not treat “nine digits” as “Social Security Number.” The generator on this site skips the reserved prefixes people actually mean when they say “not a real SSN pattern.”

Randomization also broke “this group has not been issued yet” checks. After 2011 they are theater. If a KYC vendor still sells group issuance order as a live signal, ask for a dated methodology.

Timeline showing pre-2011 geographic area numbers versus randomized assignment after June 2011
Geography was a historical accident of issuance. After 2011, the first three digits are not a state sticker.

What format-only means

Format-only means: hyphens in the right places, nine digits, no banned area, no 00 group, no 0000 serial. That is a shape check. It is closer to “does this look like a phone number” than to “is this a subscriber.” There is no Luhn digit. There is no mod-97. Compare that to an IBAN, where at least the checksum catches typos. I wrote about that arithmetic in IBAN mod-97. SSNs do not get that courtesy.

The SSN validator on Randomly is honest about this. It will tell you the string is well-formed. It will not call SSA. It will not tell you the number is unassigned. It will not tell you the holder is alive. Anyone who needs those answers is in a regulated workflow with SSA’s own verification services, not a static site with a text box.

I still want the shape check in forms. Users type 8 digits. Users paste with spaces. Users put the hyphens in the serial. Catch that in the browser before you store a broken string. Just do not rename the check “verified identity.”

When I seed demo users, I generate a fresh SSN-shaped value and I label the column ssn_format or ssn_fake. If the column is named ssn, someone will export it to a spreadsheet titled “customers.” Names matter. So does the rest of the row. A fake SSN next to a real email is still a mess. Keep the whole fixture synthetic. The longer note on that habit is PII-safe test data.

Invalid on purpose

000-xx-xxxx should fail. 666-xx-xxxx should fail. xxx-00-xxxx should fail. xxx-xx-0000 should fail. Advertisements used 987-65-4320 through 987-65-4329 for years; SSA had to deal with people who thought those were theirs. Some test ranges show up in old IRS and SSA documentation. I do not treat a viral “this is the official test SSN” tweet as a spec. I skip the structurally impossible pieces and I randomize the rest.

Area 666 is the one people ask about in comments. SSA does not issue it. Your generator should not either, unless you are writing a test that asserts rejection. Same for all-zero fields. If a QA person needs an invalid sample, give them an invalid sample on purpose. Do not sprinkle invalid numbers into a “valid looking” batch and hope someone notices.

ITIN numbers often start with 9 and follow a different middle-digit pattern. Mixing ITIN rules into an SSN validator is how you get a function named isSsn that sometimes means “tax identifier shaped.” Be explicit. If your form accepts ITIN, say so. If it does not, reject the 9xx range or route it to a different check.

Why I will not ship a live lookup

Because a public website that “checks if an SSN is real” is a magnet for abuse. Even a well-intentioned cache of issued/unissued ranges becomes a targeting aid. SSA’s own verification APIs exist for employers and benefit programs under agreements. I am not those employers. Randomly is a browser toolbox. The generator runs locally. Nothing you type is a good reason for me to hold it. See privacy.

There is also a product honesty problem. People want a green checkmark. Green checkmarks on identity data create liability. I would rather a yellow “looks like the pattern” than a fake authority stamp. The same stance shows up on the VAT validator: format and country checksum where we have them, not a live tax-authority session unless the page says so. For VAT, that split is its own post: VAT checksums versus VIES.

Browser SSN generator showing a sample number and a note that it is format-only
Generate, copy, paste into a fixture. The warning on the page is the feature.

How the generator picks digits

It draws nine digits with a CSPRNG in the page, then rejects draws that hit reserved area numbers, a zero group, or a zero serial. That is rejection sampling, the same idea I use for dice so the modulo does not bias the roll. If you care about that bias, the dice post is fair dice. For SSNs the range is small. Rejection is cheap. A biased “just take n % 900” area number would over-represent low prefixes. I do not want even a fake dataset that looks like 1960s New England.

I do not mimic the old geographic distribution. Randomized-looking prefixes are more honest for a 2026 fixture. Hyphenation is display. Store compact or store with hyphens, but pick one. Normalize on the way in. The validator should accept both and compare the compact form.

Forms, regex, and false comfort

A reasonable client check is: strip non-digits, require length 9, reject known-impossible fields, then show the hyphenated display. That is enough for a signup form that should not block a real applicant with a clever regex. Do not require the user to type hyphens. Do not forbid them. I have watched an accessibility bug report where the mask fought a password manager and the SSN field ate two digits.

Server-side, repeat the same checks. Then stop. Do not build a statistical “this SSN looks foreign” model from prefixes. Do not log full SSNs in plaintext. If you must log a validation failure, log “failed format” and a request id. Truncation of the last four still identifies people in small cohorts. Prefer not logging the number at all.

Payment fields next to identity fields get the same rule. Luhn-valid cards are not charged cards. See Luhn test cards.

What I tell QA

Use the generator. Make five users. Put the values in a secrets-ignore fixture or a local .env that never gets committed. If a screenshot will be public, blur the field even when the number is fake. Viewers cannot tell. They will Google it. They will call it a leak.

If a test needs a specific invalid prefix, hard-code rejects_area_666. If legal asks whether we “validate SSNs,” answer with the verb they mean: format check yes, SSA verification no.

Adjacent identifiers

EIN, state IDs, and phone numbers are different shapes. Split the jobs. Never search a generated SSN in production “to see if we already have it.” That turns fake data into a probe of real data. If support pastes an SSN into chat, redact it even on a test account.

Frequently asked questions

Is a generated SSN unique in the real SSA file?

I do not know and I do not check. Nine digits are a small space. Collisions with living people are possible in theory. That is why these values are for closed test systems, not for filing taxes or credit applications. If a collision would hurt someone, you are using the wrong tool.

Can I decode a state from the first three digits?

For numbers issued before randomization, sometimes, as a historical guess. For numbers after June 2011, no. Do not ship a state decoder in 2026 and call it accurate.

Why not add a fake checksum?

Because SSA did not. Inventing one would make your fixtures fail any honest format check and would train your team that SSNs work like credit cards. They do not. See Luhn for the algorithm that is a checksum.

Does Randomly store generated SSNs?

No. The page runs in your browser. Read privacy. Do not paste real SSNs into the box to “see if they validate.” Use the validator only on strings you already treat as test data.