METODOLOGÍA · REFERENCIA
Luhn vs Mod-11: comparativa de algoritmos de dígito verificador
Luhn y Mod-11 son los dos algoritmos de dígito verificador más usados en el mundo. Luhn se usa en tarjetas de pago e IMEI; Mod-11 predomina en identificadores tributarios de LATAM. Esta página explica cuándo usar cada uno, por qué Mod-11 detecta más errores de transposición, y enumera 12 edge cases que complican ambas implementaciones en producción.
¿Por qué existen dos algoritmos?
Luhn y Mod-11 son los dos algoritmos de dígito verificador más usados en el mundo. Cada uno fue diseñado con trade-offs distintos. Conocer cuál usa cada identificador evita implementar el algoritmo equivocado y perder semanas depurando falsos positivos.
Luhn (IBM, 1954, patente US2950048A): desde el dígito verificador (posición más a la derecha), moverse hacia la izquierda alternando — duplicar cada segundo dígito. Si el doble supera 9, restar 9. Sumar todos. Si la suma es divisible por 10, válido. Siempre produce un dígito decimal (0–9).
Mod-11: suma × pesos, resto mod 11, dígito = 11 − resto. Cada identificador define sus propios pesos. Si el resultado es 10, el número es estructuralmente inválido (algunos sistemas lo representan como X o K). Si es 11, se mapea a 0.
¿Cuándo usar cada uno?
| Identificador | Algoritmo | Notas |
|---|---|---|
| Tarjetas de crédito/débito | Luhn | Visa, Mastercard, Amex, Discover |
| IMEI | Luhn | 15 dígitos, último es check digit |
| CUIT / CUIL (AR) | Mod-11 | Pesos [5,4,3,2,7,6,5,4,3,2] |
| CPF (BR) | Mod-11 | Doble dígito, pesos 10→2 y 11→2 |
| CNPJ (BR) | Mod-11 | Doble dígito, pesos distintos |
| RUT-CL (Chile) | Mod-11 | Pesos [2,3,4,5,6,7], dígito puede ser K |
| NIT (Colombia) | Mod-11 | Pesos [3,7,13,17,19,23,29,37,41,43,47] |
| IBAN | Mod-97 | ISO 13616, resultado debe ser 1 |
| RFC (MX) | Propietario SAT | Homoclave derivada de tablas internas SAT |
| CURP (MX) | Propietario SAT | Sin dígito verificador estándar público |
¿Por qué Mod-11 es preferido en tax IDs?
Luhn detecta todos los errores de un dígito y la mayoría de transposiciones de dígitos adyacentes — pero no detecta la transposición del par 09 ↔ 90.
Mod-11, al usar el módulo primo 11, detecta todos los errores de un dígito y todas las transposiciones de dos dígitos adyacentes. Esto lo hace más robusto para identificadores donde un error tipográfico en cualquier posición es inaceptable.
La desventaja de Mod-11 es que el dígito verificador puede ser 10 — lo que complica campos de solo dígitos. Luhn siempre produce un dígito decimal (0–9). Esta es la razón por la que las tarjetas de crédito usan Luhn: a escala de Visa/Mastercard, la compatibilidad con campos numéricos de 16 dígitos es crítica.
Edge cases que una implementación simple no maneja
- Luhn no detecta el par 09 ↔ 90: si alguien transpone un 0 y un 9 adyacentes en un número de tarjeta, Luhn no lo detecta. Este es el único tipo de transposición que escapa al algoritmo.
- Mod-11 puede producir dígito = 10: cuando el resto es 1, el dígito esperado sería 10 — un número que no cabe en un campo de un solo dígito. Cada implementación de Mod-11 debe decidir si esto significa "inválido" o lo representa con X o K.
- Pesos distintos por identificador: CUIT usa [5,4,3,2,7,6,5,4,3,2], CPF usa [10,9,8,...,2] y [11,10,...,2], NIT Colombia usa primos. Copiar la implementación de un identificador y usarla para otro producirá validaciones incorrectas.
- Luhn con espacios en el número de tarjeta: el formato visual de tarjetas incluye espacios cada 4 dígitos (4532 0151 1283 0366). Sin strip previo, el algoritmo falla o produce resultados incorrectos.
- Mod-11 con doble dígito verificador: CPF y CNPJ tienen dos dígitos verificadores calculados secuencialmente — el segundo depende del primero. Una implementación que calcule ambos en paralelo fallará.
- IMEI y Luhn: el IMEI de 15 dígitos usa Luhn. Pero algunos IMEIs tienen 17 dígitos (con TAC y serial extendidos). Un validador que asuma longitud 15 fija rechazará IMEIs válidos de algunos fabricantes.
- Luhn para detección de errores de digitación, no de fraude: Luhn detecta errores tipográficos comunes, no fraude. Un número de tarjeta robado pasa Luhn. Esta confusión lleva a implementaciones que asumen validez = legitimidad.
- Mod-11 con remainder == 0 → dígito = 0, no 11: variación crítica que distintos países implementan diferente. CUIT: si resto=0 → check=0. CPF: si resto < 2 → check=0. Son reglas distintas que no son intercambiables.
- RUT chileno con dígito K: cuando Mod-11 produce dígito=10, el RUT chileno lo representa como K. Un sistema que solo acepta 0-9 como dígito verificador rechazará todos los RUTs con K — un porcentaje no trivial de la población.
- Batch de tarjetas: compilación de regex: validar millones de tarjetas en un loop que recompila la expresión regular en cada iteración es innecesariamente lento. Luhn no requiere regex, pero los pasos de normalización previos sí.
- Números de cuenta bancaria que parecen tarjetas: algunos sistemas bancarios latinoamericanos usan 16 dígitos para cuentas que pasan Luhn por coincidencia. No todos los números de 16 dígitos que pasan Luhn son tarjetas.
- Diferencia entre "número de tarjeta válido" y "tarjeta activa": Luhn solo verifica el checksum del número. Una tarjeta vencida, bloqueada o inexistente puede tener un número que pasa Luhn. Para verificar actividad se necesita un authorization request al emisor.
¿Querés saltarte todo esto?
Manejar todos estos edge cases en producción cuesta semanas de testing y mantenimiento permanente conforme cambian las reglas regulatorias. La API de Normadata maneja todo lo de arriba — incluyendo los casos que ni listamos aquí — con una sola llamada REST.
Fuentes
Luhn: US Patent 2950048A, IBM (1954). Mod-11: literatura académica general sobre códigos detectores de error, incluyendo Verhoeff (1969) y análisis comparativos publicados en el Journal of Applied Statistics.