ID Number Formats Worldwide: SSN, SIN, NINO & Check Digits
National ID number formats across the US, Canada, UK, France, and Germany: check-digit algorithms (Luhn, mod-97, weighted) and reserved test ranges.
By FakeName Editorial TeamPublished June 25, 2026Last updated June 25, 20269 min read
A national ID number is not a random string. It is a fixed-length code with a defined character set, reserved sub-ranges the issuing authority promises never to use, and often a check digit computed from the other characters so software can reject typos before they hit a database. This article documents the structure and validation rules for five widely encountered schemes (US SSN, Canadian SIN, UK NINO, French INSEE, German Steuer-ID) and explains why a number can pass every format check and still have belonged to no one.
Everything here is written for testing and validation. The example numbers, and the ranges our tools draw from, come from never-issued and reserved blocks, so they exercise a form without ever matching a living person.
What is the difference between a format-valid ID and an issued one?
A format-valid ID obeys its scheme's structural rules: correct length, an allowed character set, no forbidden sub-range, and a check digit that recomputes correctly. An issued ID is one a government actually assigned to a person. Every issued number is format-valid, but most format-valid numbers were never issued, and no offline validator can tell the two apart.
That gap is the foundation of safe test data. Many schemes set aside ranges the issuer guarantees it will never assign. A generator that draws only from those ranges produces output that satisfies a validator while staying guaranteed-fictional. The US Social Security Administration, for example, states it will never issue a number with an area number of 900 through 999 [ssa-randomization], which is why those numbers are standard for documentation and QA.
How are the five national ID schemes structured?
Each of the five schemes is a fixed-length numeric or alphanumeric code with its own reserved ranges, and only three carry an arithmetic check digit. The table below lists length, check-digit method, and never-issued ranges for each. Lengths exclude separators (spaces, hyphens) that are added for display only.
| Country | ID name | Format / length | Check-digit method | Reserved / never-issued |
|---|---|---|---|---|
| United States | Social Security Number (SSN) | 9 digits, AAA-GG-SSSS | None | Area 000, 666, 900-999; group 00; serial 0000 [ssa-randomization] |
| Canada | Social Insurance Number (SIN) | 9 digits, 3-3-3 | Luhn (digit 9) | First digit 0 not assigned; first digit 9 = temporary residents [sin-wikipedia] |
| United Kingdom | National Insurance Number (NINO) | 2 letters + 6 digits + 1 letter (suffix A-D) | None (prefix rules only) | TN, BG, GB, KN, NK, NT, ZZ and others excluded as prefixes [hmrc-nim39110] |
| France | INSEE / NIR | 13 digits + 2-digit key (15 total) | mod-97 key | Provisional numbers begin with 7 or 8 [insee-wikipedia] |
| Germany | Steuer-ID (tax ID) | 11 digits | ISO/IEC 7064 (digit 11) | Leading digit cannot be 0 [steuerid-wikipedia] |
Two patterns matter for implementers. Only the SIN, INSEE, and Steuer-ID carry a real check digit, so validation strength swings widely by country. And every scheme reserves something, whether an area range, a leading digit, or a letter prefix, which is exactly what makes principled test-data generation possible.
How does the US SSN work without a check digit?
The SSN is nine digits grouped as area (3), group (2), and serial (4), with no checksum at all. On June 25, 2011, the SSA switched to randomization, which dropped the old geographic meaning of the area number but kept the exclusions: area 000, 666, and 900-999 are never issued, the group cannot be 00, and the serial cannot be 0000 [ssa-randomization]. With no check digit, a validator can only apply those structural rules. Our SSN validator flags the reserved ranges rather than claiming any number is real.
How does the Canadian SIN use the Luhn check digit?
The SIN is nine digits, shown in three groups of three, and its ninth digit is a Luhn check digit computed from the first eight [sin-wikipedia]. A leading 0 is not assigned to any province, and a leading 9 marks temporary residents. The checksum makes SIN validation meaningfully stronger than SSN validation, because a single mistyped digit is almost always caught. The SIN generator and validator produces Luhn-valid samples and checks numbers you paste in.
What are the UK NINO prefix rules?
A NINO is two prefix letters, six digits, and a suffix letter from A to D, for example QQ 12 34 56 C. It has no arithmetic check digit; validity rests on prefix rules. HMRC excludes the combinations BG, GB, KN, NK, NT, TN, and ZZ from allocation, and treats TN as a temporary reference rather than a real prefix [hmrc-nim39110]. The letters D, F, I, Q, U, and V are barred in either position, and O is barred as the second letter. The NINO generator and validator encodes these rules and prefers reserved prefixes for generated samples.
The characters D, F, I, Q, U, and V are not used as either the first or second letter of a National Insurance number prefix.
| Rule | Detail | Example outcome |
|---|---|---|
| First and second letter exclusions | D, F, I, Q, U, V never used in either position | VV 12 34 56 A is invalid [hmrc-nim39110] |
| Second-letter exclusion | O not allowed as the second letter | AO 12 34 56 A is invalid [hmrc-nim39110] |
| Excluded prefix combinations | BG, GB, KN, NK, NT, TN, ZZ are not allocated | TN 31 12 55 M is a reserved temporary reference [hmrc-nim39110] |
| Suffix | Single letter A, B, C, or D only | QQ 12 34 56 E is invalid [hmrc-nim39110] |
How do the French INSEE and German Steuer-ID numbers compute their check digits?
The French INSEE number (NIR) is 13 digits encoding sex, year and month of birth, department, and a sequence, followed by a two-digit *cle de controle* computed with a mod-97 rule [insee-wikipedia]. The German Steuer-ID is 11 digits whose eleventh digit is a check digit from an ISO/IEC 7064 procedure, with a leading digit that is never 0 [steuerid-wikipedia]. The two show why no single universal checksum works: INSEE uses mod-97 while the Steuer-ID uses an ISO/IEC 7064 MOD 11,10 chain.
Which check-digit algorithms do these schemes use?
Three algorithm families cover the schemes above and most identifiers you will meet: Luhn (mod 10), mod-97 from ISO/IEC 7064, and the ISO/IEC 7064 MOD 11,10 chain, plus assorted weighted-modulus schemes for tax and VAT IDs. The table names each algorithm, where it is used, and the error classes it is designed to catch.
| Algorithm | Where used | Modulus | Catches |
|---|---|---|---|
| Luhn | Canadian SIN, payment cards | mod 10 | All single-digit errors; most adjacent transpositions [luhn-wikipedia] |
| mod-97 (ISO/IEC 7064) | IBAN, French INSEE key | mod 97 | All single-digit errors and transpositions; ~99% of random errors [iban-iso13616] |
| ISO/IEC 7064 MOD 11,10 | German Steuer-ID | mod 11/10 chain | All single-digit and adjacent transposition errors [steuerid-wikipedia] |
| Weighted modulus | Many tax/VAT IDs | varies (e.g. mod 11) | Single-digit errors; some transpositions depending on weights |
How do you validate a SIN with Luhn, step by step?
To validate a SIN with Luhn, work from the rightmost digit, double every second digit moving left, subtract 9 from any doubled value over 9, sum everything, and confirm the total is divisible by 10. Take the test number 046 454 286 and trace it through.
- Number the digits from the right: 6(1), 8(2), 2(3), 4(4), 5(5), 4(6), 6(7), 4(8), 0(9).
- Double the even-position digits (2, 4, 6, 8): 8 to 16, 4 to 8, 4 to 8, 4 to 8. Reduce any result over 9 by subtracting 9, so 16 becomes 7. These become 7, 8, 8, 8.
- Leave the odd-position digits unchanged: 6, 2, 5, 6, 0.
- Sum everything: (6 + 2 + 5 + 6 + 0) + (7 + 8 + 8 + 8) = 19 + 31 = 50.
Because 50 is divisible by 10, 046 454 286 is Luhn-valid [luhn-wikipedia]. A validator accepts its format. It stays fictional because it was generated, not issued.
How do reserved ranges give you safe test data?
Reserved ranges give you test data that clears format validators while being structurally incapable of matching an issued identifier. A generator that emits SSNs in the 900-999 area, Luhn-valid SINs on documentation patterns, and NINOs on excluded prefixes like TN produces fixtures that are safe for QA pipelines, form-fill testing, demo environments, and privacy-preserving sample datasets.
| Scheme | Safe-for-testing range | Why it is safe |
|---|---|---|
| US SSN | Area number 900-999 | SSA states it will never issue these area numbers [ssa-randomization] |
| US SSN | Area 000 or 666, group 00, serial 0000 | Structurally excluded from issuance [ssa-randomization] |
| Canada SIN | Leading digit 0 (still Luhn-valid) | First digit 0 is not assigned to any province [sin-wikipedia] |
| UK NINO | TN and other excluded prefixes | TN is a temporary reference, never a real allocation prefix [hmrc-nim39110] |
| France INSEE | Provisional numbers beginning 7 or 8 | Marked provisional rather than issued [insee-wikipedia] |
This is also where the ethical line sits. Generated identifiers exist for testing, QA, form-filling, and privacy. They must never pass a legally required identity or eligibility check, open accounts, claim benefits, or impersonate a real person. Each of those is fraud and is illegal in most jurisdictions, whether or not the number is format-valid. Start from the identity generator to pick a generator, and reach for the validators above to confirm your validation logic matches each specification.
The engineering takeaway is concrete. Build per-scheme validators that encode the real length, character set, reserved ranges, and the correct check-digit algorithm. Treat any pass as *format-valid only*. Source your test fixtures from never-issued ranges so your suite never embeds a real person's number.
References & sources
- Social Security Number Randomization — U.S. Social Security Administration
- Social Insurance Number — Wikipedia
- NIM39110: National Insurance Numbers (NINOs): Format and Security — HM Revenue & Customs
- INSEE code / NIR (French national identification number) — Wikipedia
- Steuerliche Identifikationsnummer (German tax identification number) — Wikipedia
- Luhn algorithm — Wikipedia
- ISO 13616-1: International Bank Account Number (IBAN) and mod-97 check — International Organization for Standardization
Frequently asked questions
What is the difference between a format-valid ID and an issued ID?+
A format-valid ID satisfies its scheme's structural rules: correct length, allowed character set, no forbidden sub-range, and a check digit that recomputes correctly. An issued ID is one a government actually assigned to a person. Every issued number is format-valid, but the vast majority of format-valid numbers were never issued. Offline validators can only confirm the former, because issuance registers are private.
Why does the Canadian SIN use the Luhn algorithm?+
The SIN is nine digits, and its ninth digit is a Luhn check digit computed from the first eight. Luhn (mod 10) catches every single-digit transcription error and most adjacent transpositions, the two most common data-entry mistakes. It is the same checksum used on payment-card numbers, so libraries exist in every language and the math is trivial to implement.
What is the TN prefix in a UK National Insurance number?+
TN is a temporary-reference prefix HMRC explicitly excludes from valid NINO allocation. Together with BG, GB, KN, NK, NT, and ZZ, it never appears on an issued number, which makes the TN range a safe choice for documentation and test data where a real NINO must never surface.
Can I use a generated ID number to sign up for a real service?+
No. Generated numbers are fictional and exist only for software testing, QA, form-filling, and privacy work. Using a fabricated identifier to pass a legally required identity or eligibility check, open a financial account, claim benefits, or impersonate someone is fraud and is illegal in most jurisdictions. Generators draw from never-issued and reserved ranges precisely so the output cannot belong to a real person.
Does the US Social Security Number have a check digit?+
No. The nine-digit SSN has no checksum. Validation is limited to structural rules and known exclusions: area numbers 000, 666, and 900-999 are never issued, the group cannot be 00, and the serial cannot be 0000. Because there is no check digit, SSN format validation is weaker than for the SIN or the French INSEE number.
Which check-digit algorithm should I implement for international ID fields?+
Match the algorithm to the scheme: Luhn for the Canadian SIN, mod-97 (ISO/IEC 7064) for IBANs and the French INSEE key, and ISO/IEC 7064 MOD 11,10 for the German Steuer-ID. Do not apply one algorithm universally. Each country's specification defines its own method, and using the wrong one rejects valid numbers as false negatives.