Generator · Portuguese data
Portuguese Cartão de Cidadão number
Endpoint GET /v1/pt/cartao-cidadao
What it covers
Returns a valid Portuguese Cartão de Cidadão (Citizen Card) document number with correct NIC and final check digits. Set `invalid=true` for a number with a deliberately wrong final check character, or `edge=true` for valid edge cases.
How it’s calculated
The Portuguese Cartão de Cidadão document number carries two check characters: a mod-11 check digit over the 8-digit NIC, and a final Luhn/mod-10 check digit over the eleven preceding alphanumeric characters (NIC + NIC-check + 2-char version).
Algorithm
- The full document number is 12 characters: 8 NIC digits, then the NIC check digit (1), then a 2-character version code (letters/digits, e.g. ZZ), then the final check digit (1). Layout: NIC(8) + NICcheck(1) + version(2) + finalCheck(1).
- STEP A — NIC check digit (the 9th character), a mod-11 check over the 8 NIC digits.
- A1. Take the 8 NIC digits d1..d8 and apply position weights [9, 8, 7, 6, 5, 4, 3, 2] (d1 gets weight 9, ... d8 gets weight 2).
- A2. Compute the weighted sum: sum = 9*d1 + 8*d2 + 7*d3 + 6*d4 + 5*d5 + 4*d6 + 3*d7 + 2*d8.
- A3. base = sum mod 11.
- A4. raw = 11 - base (this is the 'complement' style).
- A5. Apply the 'mod11-mod10' overflow rule: checkDigit = (raw mod 11) mod 10. Concretely a raw of 11 -> 0 and a raw of 10 -> 0; any other raw (1..9) is used as-is. This overflow guarantees a single digit for every prefix, so nothing is ever redrawn.
- A6. Append this digit after the 8 NIC digits to form the 9-character NIC block.
- STEP B — final check digit (the 12th character), a Luhn / mod-10 variant over the eleven preceding characters = NIC block (9) + version (2).
- B1. Form the 11-character string c[0..10] = NIC(8) + NICcheck(1) + version(2).
- B2. Convert each character to its alphanumeric value: '0'-'9' -> 0-9, 'A'-'Z' -> 10-35 (so 'Z' = 35). Version letters therefore contribute values 10-35.
- B3. Scan right-to-left. Starting with the rightmost character (index 10), double every SECOND value: the rightmost is doubled, its left neighbour is not, the next is doubled, and so on (doubling flag starts true at the rightmost position).
- B4. Luhn reduction: whenever a doubled value exceeds 9, subtract 9 from it ONCE. Note: because letter values can be up to 35, a doubled value can be as high as 70; the rule subtracts 9 only once (e.g. 70 -> 61), it does NOT reduce to a single digit.
- B5. Sum all the (possibly doubled/reduced) values into total.
- B6. finalCheck = (10 - (total mod 10)) mod 10.
- B7. Append finalCheck as the 12th character. The complete document is NIC(8) + NICcheck(1) + version(2) + finalCheck(1).
Worked example
NIC 12345678, version ZZ -> document 123456789ZZ? (computing the final 12th check digit)
First derive the NIC check digit (9th char) via STEP A on NIC = 12345678.
Weighted sum = 9*1 + 8*2 + 7*3 + 6*4 + 5*5 + 4*6 + 3*7 + 2*8 = 9+16+21+24+25+24+21+16 = 156.
base = 156 mod 11 = 2 (11*14 = 154, 156-154 = 2).
raw = 11 - 2 = 9. Overflow mod11-mod10: (9 mod 11) mod 10 = 9. NIC check digit = 9.
NIC block = 123456789; with version ZZ the eleven-char payload is 123456789ZZ.
Now STEP B (Luhn/mod-10) over 123456789ZZ, right-to-left, alphanumeric values (Z = 35), doubling the rightmost first:
index10 'Z'=35 doubled -> 70 -> 70-9 = 61
index9 'Z'=35 not doubled -> 35
index8 '9'=9 doubled -> 18 -> 18-9 = 9
index7 '8'=8 not doubled -> 8
index6 '7'=7 doubled -> 14 -> 14-9 = 5
index5 '6'=6 not doubled -> 6
index4 '5'=5 doubled -> 10 -> 10-9 = 1
index3 '4'=4 not doubled -> 4
index2 '3'=3 doubled -> 6
index1 '2'=2 not doubled -> 2
index0 '1'=1 doubled -> 2
total = 61+35+9+8+5+6+1+4+6+2+2 = 139.
finalCheck = (10 - (139 mod 10)) mod 10 = (10 - 9) mod 10 = 1.The final check digit is 1, giving the complete Cartão de Cidadão document number 123456789ZZ1.
Edge cases
- The version field is 2 characters and can contain letters; the generator draws from common versions ['ZZ','ZY','ZX','ZW','ZV'] where 'ZZ' is the first-ever issue and each reissue steps the second character back. Because version letters map to alphanumeric values up to 35, the final Luhn step can double a value as high as 35 (to 70).
- The NIC is drawn with a first digit 1-9 (non-leading-zero shape), so the standard generated NIC block is 8 digits with no leading zero, though the validator accepts any 8-digit NIC.
Gotchas
- The final check digit's Luhn step subtracts 9 only ONCE from an over-9 doubled value (value -= 9), it does NOT iteratively digit-sum. Because letter values exceed 9, a doubled 35 becomes 70 then 61 — a two-digit contribution — not the single-digit result naive Luhn implementations assume.
- The NIC check uses the 'mod11-mod10' overflow, so a complement raw of both 10 and 11 collapses to 0 (historically a NIC check that worked out to 10 was recorded as 0). This means the mod-11 primitive never returns undefined here, and no prefix ever has to be redrawn.
- There are TWO separate check characters computed by different algorithms (mod-11 for the 9th char, Luhn/mod-10 for the 12th char) — a valid document must satisfy both independently.
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 numbers 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 document number with a deliberately wrong final check character. |
| seed | integer | Integer seed for reproducible output: the same seed always yields the same record. |
Response fields
| Field | Type | Description |
|---|---|---|
| value | string | The full 12-character Cartão de Cidadão document number. |
| nic | string | The 8-digit NIC (civil identification number). |
| version | string | The two-character version block, e.g. `ZZ`. |
Other generators for Portugal
Portuguese companyPortuguese company namePortuguese email addressPortuguese IBANPortuguese NIFPortuguese personPortuguese person namePortuguese product or service offeringPortuguese vehicle registration plate
See all generators for Portugal →The same kind of identifier elsewhere
Austrian data · Austrian FirmenbuchnummerAustrian data · Austrian SteuernummerAustrian data · Austrian UIDBelgian data · Belgian OndernemingsnummerBulgarian data · Bulgarian EIKCzech data · Czech IČODanish data · Danish CVRDutch data · Dutch btw-idDutch data · Dutch KvK numberDutch data · Dutch RSINEstonian data · Estonian KMKREstonian data · Estonian registrikoodFrench data · French SIRENGerman data · German HandelsregisternummerGerman data · German Personalausweis numberGerman data · German USt-IdNrGerman data · German Wirtschafts-IdNrHungarian data · Hungarian adószámHungarian data · Hungarian cégjegyzékszámIrish data · Irish CRO numberIrish data · Irish VAT numberItalian data · Italian Partita IVALatvian data · Latvian registracijas numursLithuanian data · Lithuanian įmonės kodasLithuanian data · Lithuanian PVM (VAT) numberLuxembourg data · Luxembourg TVAMaltese data · Maltese identity card numberMaltese data · Maltese VAT numberPolish data · Polish driving licence numberPolish data · Polish ID card numberPolish data · Polish KRS numberPolish data · Polish land and mortgage register numberPolish data · Polish NIPPolish data · Polish passport numberPolish data · Polish REGONRomanian data · Romanian CUI/CIFSlovak data · Slovak IČ DPHSlovak data · Slovak IČOSpanish data · Spanish CIFSwedish data · Swedish organisationsnummer
Try it