Generator · Spanish data
Spanish DNI
Endpoint GET /v1/es/dni
What it covers
Returns a valid Spanish DNI (national identity / tax number) with a correct control letter computed from the 8 digits modulo 23. Set `invalid=true` for a DNI with a deliberately wrong control letter.
How it’s calculated
The Spanish DNI control character is a single letter chosen from a fixed 23-letter alphabet by the residue of the 8-digit body modulo 23.
Algorithm
- Take the 8-digit numeric body of the DNI as an integer (leading zeros allowed; parse the whole 8-digit string as a base-10 number).
- Compute the remainder r = body mod 23. The result is in the range 0..22.
- Use the fixed control-letter alphabet (index 0 first): TRWAGMYFPDXBNJZSQVHLCKE.
- The control letter is the character at index r within that alphabet (0-based).
- Append that letter to the 8-digit body to form the full DNI, e.g. body + letter.
Worked example
DNI body 12345678 -> 12345678?
Body as integer = 12345678.
12345678 mod 23: 23 * 536768 = 12345664; 12345678 - 12345664 = 14, so r = 14.
Alphabet TRWAGMYFPDXBNJZSQVHLCKE indexed 0-based: T=0, R=1, W=2, A=3, G=4, M=5, Y=6, F=7, P=8, D=9, X=10, B=11, N=12, J=13, Z=14.
Index 14 = Z.The control letter is Z, so the full DNI is 12345678Z.
Edge cases
- A body that is an exact multiple of 23 gives residue 0, mapping to the first alphabet letter T (the generator's 'control-t' edge case exercises this).
- Leading-zero bodies (first digit 0) are valid: the full 8-digit string is still parsed as an integer, so e.g. 00000023 -> 23 mod 23 = 0 -> T.
Gotchas
- The alphabet is NOT alphabetical order and does NOT include I, O, U (they are omitted to avoid confusion with digits/letters); using A=0,B=1,... will produce the wrong letter — you must use the exact string TRWAGMYFPDXBNJZSQVHLCKE.
- The modulus is 23, not a weighted checksum: no per-digit weights are applied, the whole body is taken as one integer and reduced mod 23.
- The DNI control letter doubles as the resident's NIF (tax id) check letter; the same mod-23 letter validates both.
Parameters
| Parameter | Type | Description |
|---|---|---|
| count | integer1–1000 | Number of records to return, 1–1000 (your plan may lower this). Omitted returns a single record; set it for a batch. |
| edge | boolean | Restrict output to valid edge-case DNIs from the rare corners. |
| extreme | boolean | Return a correct value wrapped in a hostile encoding (untrimmed whitespace, invisible/zero-width characters, BOM, or bidi/combining marks). Homoglyphs are excluded so the value stays machine-parseable; it still validates after normalisation. |
| invalid | boolean | Return a DNI with a deliberately wrong control letter. |
| seed | integer | Integer seed for reproducible output: the same seed always yields the same record. |
Response fields
| Field | Type | Description |
|---|---|---|
| value | string | The full DNI: 8 digits followed by the control letter. |
| digits | string | The canonical 8-digit body, leading zeros preserved. |
| letter | string | The single control letter from `TRWAGMYFPDXBNJZSQVHLCKE`. |
Other generators for Spain
Spanish CIFSpanish companySpanish company nameSpanish email addressSpanish IBANSpanish NIESpanish personSpanish person nameSpanish product or service offeringSpanish vehicle registration plate
See all generators for Spain →The same kind of identifier elsewhere
Austrian data · Austrian SVNRBelgian data · Belgian RijksregisternummerBulgarian data · Bulgarian EGNCroatian data · Croatian JMBGCroatian data · Croatian OIBCypriot data · Cyprus TICCzech data · Czech rodné čísloDanish data · Danish CPRDutch data · Dutch BSNEstonian data · Estonian isikukoodFinnish data · Finnish henkilötunnusFinnish data · Finnish Y-tunnusFrench data · French NIRGerman data · German Steuer-IdNrGreek data · Greek AFMGreek data · Greek AMKAHungarian data · Hungarian adóazonosító jelHungarian data · Hungarian személyi azonosítóHungarian data · Hungarian TAJIrish data · Irish PPSNItalian data · Italian Codice FiscaleLatvian data · Latvian personas kodsLithuanian data · Lithuanian asmens kodasLuxembourg data · Luxembourg matriculePolish data · Polish PESELPortuguese data · Portuguese NIFRomanian data · Romanian CNPSlovak data · Slovak rodné čísloSlovenian data · Slovenian davčna številkaSlovenian data · Slovenian EMŠOSwedish data · Swedish personnummer
Try it