| Code | Scope | Length | Check digit | Confidence |
|---|---|---|---|---|
MX_CURP |
personal | 18 | mod-10 over RENAPO alphabet | high |
MX_RFC_PF |
tax (natural) | 13 | mod-11 SAT homoclave | moderate |
MX_RFC_PM |
tax (jurídica) | 12 | mod-11 SAT homoclave (space-padded body) | moderate |
MX_CLAVE_ELECTOR |
personal | 18 | none (format-only + structural) | low |
MX_NSS |
personal (social security) | 11 | Luhn / mod-10 | high |
MX_CURP — Clave Única de Registro de PoblaciónUniversal personal identifier issued by RENAPO (SEGOB). Encodes initials, birth date, sex, entidad federativa, and internal consonants. Required for taxes, social security, banking, and most government interactions.
AAAA######HXXLLL## — 18 contiguous chars, no separatorsmod-10 weighted sum over the first 17 chars, mapped through a 37-character alphabet 0..9 A..N Ñ O..Z (indices 0..36).
alphabet = "0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"
sum = sum(alphabet.indexOf(c[i]) * (18 - i)) for i in 0..16
expected_dv = (10 - (sum mod 10)) mod 10
valid iff expected_dv == int(c[17])
Additional structural checks: month must be 01-12, day 01-31, sex H or M, entidad federativa one of the 32 estados + NE (nacido en el extranjero).
python-stdnum stdnum.mx.curp.valid:
- GOMC850315HDFRRR07
- MARP800101MDFRTR03
- LOPB920715HJCRRR05
- GAVA751231MNERRR07
- SANC000229HBCNNN06
- XEXX010101HNEXXXA4 (RENAPO genérica extranjero — accepted)
invalid (format):
- GOMC850315HDFRRR0 (17 chars — missing DV)
- GOMC851315HDFRRR07 (mes 13)
- GOMC850000HDFRRR07 (día 00)
- GOMC850315HZZRRR07 (entidad federativa inválida)
invalid (checksum):
- GOMC850315HDFRRR00
- MARP800101MDFRTR09
- LOPB920715HJCRRR01
Ñ policy. The standard normalizes Ñ → X at issuance, but the algorithm is defined for both. We currently accept both. Confirm whether downstream consumers prefer strict X-only.XEXX010101HNEXXXA4 validates by structure and checksum — no special-casing required. Document this as expected behavior for clients tempted to reject it.MX_RFC_PF — Registro Federal de Contribuyentes (Persona Física)Tax identifier for natural persons issued by SAT. Combines a 4-letter prefix derived from name + surnames, the 6-digit birth date, and a 3-character homoclave (assigned by SAT to disambiguate collisions; the last char is the DV).
AAAA######XXX (13 contiguous chars)mod-11 over the first 12 chars, mapped through the 38-character SAT table:
table = { ' ': 0, '0'..'9': 1..10, 'A'..'N': 11..24, '&': 25, 'O'..'Z': 26..37 }
sum = sum(table[c[i]] * (13 - i)) for i in 0..11
r = sum mod 11
dv = 11 - r
if dv == 11 -> '0'
if dv == 10 -> 'A'
else -> str(dv)
valid iff dv == c[12]
Additional checks:
X at issuance.XAXX010101000 and XEXX010101000 are accepted as valid (CFDI 4.0 placeholders).python-stdnum stdnum.mx.rfc.valid:
- MELO850315H79
- GAJA920101AB5
- PEMA751231X15
- RUDR000115AA1
- TOPA800615X90
- XAXX010101000 (SAT genérico operación con público en general)
- XEXX010101000 (SAT genérico extranjero sin RFC)
invalid (format):
- MELO850315H7 (12 chars — RFC PM length)
- 1234850315H79 (numeric prefix)
- PUTO850315ABC (forbidden palabra altisonante)
- MELO851315H79 (mes 13)
invalid (checksum):
- MELO850315H70
- GAJA920101AB0
- PEMA751231X19
stdnum, several JS implementations) but SAT does not publish it verbatim. Confidence is therefore moderate.MX_RFC_PM — Registro Federal de Contribuyentes (Persona Moral)Tax identifier for legal entities (sociedades, asociaciones, fideicomisos) issued by SAT.
AAA######XXX (12 contiguous chars)Same SAT homoclave algorithm as PF, with the 11-char body left-padded by a single space (which has table value 0) so the weighted sum aligns to 12 positions.
body12 = " " + rfc[0..10]
sum = sum(table[body12[i]] * (13 - i)) for i in 0..11
... (same r/dv rules as PF)
valid iff dv == rfc[11]
Birth date plausibility: month 01-12, day 01-31.
Same as MX_RFC_PF.
valid:
- ABC901231J45
- XYZ850615PQ5
- MEX120831RT7
- GHI001215AB5
- BBB991231X98
invalid (format):
- ABC901231J4 (11 chars)
- 1234901231J45 (numeric prefix)
- ABCXXXXXXJ45 (chars 3-8 must be digits)
- ABC901331J45 (mes 13)
invalid (checksum):
- ABC901231J40
- XYZ850615PQ0
- MEX120831RT0
MX_CLAVE_ELECTOR — Clave de Elector (credencial INE/IFE)18-character voter ID code printed on every credencial INE/IFE issued by the Instituto Nacional Electoral (INE). It is the most-presented physical ID in México daily life — fintech onboarding (Clip, Bitso, Stori, Nu MX), bank KYC (CNBV Disposiciones), telco SIM activation, and government services routinely request it.
CLAVE_ELECTOR, INE. Both resolve to this spec at the country-scoped API level.LLLLLLYYEEMMDDS### (18 contiguous chars, no separators)None — INE no publica un algoritmo de dígito verificador para la Clave de Elector. La validación de esta librería es format-only más reglas estructurales:
/^[A-Z]{6}\d{8}[HM]\d{3}$/01 y 32 (catálogo INE).01 y 12.01 y 31 (sin chequeo de mes-corto / bisiesto, alineado al estilo CURP).hasCheckDigit es false. El campo confidence es low.
valid:
- GMRPRZ85091015H123 (1985, ent 09 CDMX, 10/15, H)
- LPZNVR92151225M407 (1992, ent 15 Edo. Méx., 12/25, M)
- SNCHGL00140628H012 (2000, ent 14 Jalisco, 06/28, H)
- GVRRRZ75320101M999 (1975, ent 32 Zacatecas — boundary, 01/01)
- HRNNDZ05010715H088 (2005, ent 01 Aguascalientes — boundary, 07/15)
- PRZGRR68071231H501 (1968, ent 07 Chiapas, 12/31 — day boundary)
invalid (format):
- GMRPRZ85091015H12 (17 chars — short)
- GMRPRZ85091015H1234 (19 chars — long)
- GMR1RZ85091015H123 (digit en slot de letras)
- GMRPRZ8509101AH123 (letra en slot de dígito)
invalid (structural):
- GMRPRZ85331015H123 (entidad 33 fuera de rango)
- GMRPRZ85091315H123 (mes 13)
- GMRPRZ85091000H123 (día 00)
- GMRPRZ85091015X123 (sexo X — sólo H/M)
09 = CDMX, 15 = Edo. Méx., etc.), distinta del catálogo de 2 letras que usa CURP (DF, MC). Por eso esta spec no reutiliza el ENTIDADES set de CURP — valida directamente el rango numérico 01..32.validator.js, python-stdnum) que cubra la Clave de Elector. Esta implementación es greenfield.low hasta que INE publique un dígito verificador o aparezca una librería oficial cross-validable.MX_NSS — Número de Seguridad SocialIMSS-issued social-security number for Mexican workers and beneficiaries. Required for payroll, healthcare, retirement (Afore), and incapacities. Distinct from CURP (national ID) and RFC (tax) — most payroll systems require all three.
00000000000 (11 contiguous digits). Some IMSS-printed documents group as XX-XX-XX-XXXX-X for legibility; normalize() strips those separators idempotently.Standard Luhn / ISO/IEC 7812-1 mod-10 over the 11 digits:
from rightmost digit, double every 2nd digit
if a doubled value > 9, subtract 9
sum all digits with the doubling rule applied
valid iff sum mod 10 == 0
Additional rule: all-same-digit values (e.g. 00000000000, 11111111111) are rejected as placeholders even if they happen to be Luhn-valid.
tochotitlan/nss-validator and the IMSS portal Luhn behavior.valid (Luhn):
- 12345678903 body 1234567890, DV 3
- 01234567897 body 0123456789, DV 7
- 09876543217 body 0987654321, DV 7
invalid (format):
- "" (empty)
- 1234567890 (10 digits)
- 123456789034 (12 digits)
- 12345A67903 (non-digit)
- 00000000000 (all-same-digit placeholder)
invalid (checksum):
- 12345678900
- 12345678901
- 09876543210
None affecting the format. The IMSS portal expanded online verification in 2018 and 2024 but the 11-digit Luhn structure has been stable since the 1990s.
MX_PASAPORTE — PasaporteTravel document issued by the Secretaría de Relaciones Exteriores (SRE).
Current series follow a 1-letter + 8-digit shape (9 chars), commonly with a
leading G or N (e.g. G12345678).
None on the printed number. MRZ check digit lives in
algorithms/icao-9303.ts.
moderate — multiple secondary confirmations including consular guides; SRE
has not published a format spec.