El algoritmo de Luhn explicado: cómo funciona la validación de números de tarjeta
Cada número de tarjeta que alguna vez escribiste en un formulario fue verificado por un algoritmo de 70 años antes de salir de tu navegador. El algoritmo de Luhn —también llamado MOD 10 o algoritmo módulo 10— es la suma de verificación (checksum) que usan todas las redes de tarjetas importantes para detectar errores de escritura. Esta guía explica cómo funciona, cómo implementarlo y qué no puede hacer.
¿Qué es el algoritmo de Luhn?
El algoritmo de Luhn fue inventado por el científico de IBM Hans Peter Luhn en 1954 y patentado en 1960. Es una fórmula de suma de verificación sencilla que detecta errores accidentales en números de identificación: errores en un solo dígito, la mayoría de las transposiciones de dígitos adyacentes y algunas otras clases de errores.
No es una medida de seguridad ni un método de cifrado. Es una verificación de integridad de datos. Las redes de tarjetas agregan un dígito verificador de Luhn a cada número de tarjeta, y cualquier sistema puede verificarlo con unas pocas líneas de código y sin acceso a la red.
Cómo funciona, paso a paso
Con un número, por ejemplo 79927398713:
- Empezando por el dígito de la derecha y avanzando hacia la izquierda, duplica cada segundo dígito.
- Si al duplicar obtienes un valor mayor que 9, resta 9 (equivale a sumar entre sí los dos dígitos del resultado).
- Suma todos los dígitos: tanto los duplicados como los que quedaron intactos.
- Si el total es divisible por 10, el número pasa la verificación.
Para 79927398713, los dígitos procesados suman 70, así que el número es válido.
En una tarjeta real, el dígito verificador no se conoce de antemano: el emisor lo calcula para que el número final pase la verificación. Por eso todo número de tarjeta válido del mundo cumple la misma condición de una línea: total % 10 === 0.
Implementación
JavaScript
function isValidLuhn(number) {
const digits = number.replace(/\D/g, '');
let sum = 0;
let double = false;
for (let i = digits.length - 1; i >= 0; i--) {
let digit = Number(digits[i]);
if (double) {
digit *= 2;
if (digit > 9) digit -= 9;
}
sum += digit;
double = !double;
}
return sum % 10 === 0;
}
Python
def is_valid_luhn(number: str) -> bool:
digits = [int(c) for c in number if c.isdigit()]
total = 0
for index, digit in enumerate(reversed(digits)):
if index % 2 == 1:
digit *= 2
if digit > 9:
digit -= 9
total += digit
return total % 10 == 0
PHP
function isValidLuhn(string $number): bool
{
$digits = preg_replace('/\D/', '', $number);
$sum = 0;
$double = false;
for ($i = strlen($digits) - 1; $i >= 0; $i--) {
$digit = (int) $digits[$i];
if ($double) {
$digit *= 2;
if ($digit > 9) {
$digit -= 9;
}
}
$sum += $digit;
$double = !$double;
}
return $sum % 10 === 0;
}
Puedes probar cualquier número al instante con nuestro validador de Luhn.
Qué no detecta Luhn
El algoritmo de Luhn es deliberadamente simple, lo que también lo hace fácil de engañar:
- No puede decir si una tarjeta existe. Cualquier número puede hacerse válido según Luhn, incluidos números de BIN que nunca se emitieron. Luhn no dice nada sobre la cuenta, el saldo ni el emisor.
-
Se le escapan algunas transposiciones. Intercambiar
09y90produce la misma suma, así que esa transposición en particular no se detecta. La mayoría de las otras transposiciones de dígitos adyacentes sí se detectan. - No valida la longitud ni el BIN. Las reglas de longitud y los rangos de BIN son verificaciones aparte. Un número de 16 dígitos puede pasar Luhn y aun así ser inválido para un BIN de Amex de 15 dígitos.
- No es una función de seguridad. Los atacantes generan números válidos según Luhn sin ningún esfuerzo; la verificación existe para proteger a los usuarios de errores de escritura, no a los sistemas del fraude.
Por qué esto importa a los desarrolladores
Si construyes algo que acepta datos de tarjetas, te vas a encontrar con Luhn en al menos tres lugares:
- Validación en el cliente: dale al usuario una respuesta inmediata antes de enviar el formulario y evita un ida y vuelta a tu proveedor de pagos por un error de escritura evidente.
- Generación de datos de prueba: los fixtures, las seeds y los scripts de QA necesitan números que pasen la validación, lo que significa calcular bien el dígito verificador. Eso es justamente lo que hace nuestro generador de tarjetas de prueba.
- Análisis y normalización: cuando los números llegan de clientes, hojas de cálculo o logs, Luhn es la verificación básica más barata antes de enviar cualquier cosa a una pasarela de pago.
Cómo generar números de prueba válidos
Para generar números de prueba estructuralmente válidos a partir de cualquier BIN, usa el generador de tarjetas de Namso Gen. Calcula por ti el dígito verificador de Luhn y puede agregar fechas de vencimiento y CVV. Si quieres enumerar todas las combinaciones de un patrón, el generador avanzado acepta comodines x.
Para ver en detalle las verificaciones que van más allá de Luhn, consulta los números BIN explicados o revisa cualquier prefijo con el verificador de BIN.
Resumen
- Luhn (MOD 10) es una suma de verificación, no una validación de existencia ni una medida de seguridad.
- Duplicar cada segundo dígito desde la derecha, sumar y comprobar si el total es divisible por 10 es todo lo que hay que hacer.
- Todas las redes de tarjetas importantes lo usan, y por eso todo número de tarjeta real pasa la verificación.
- Úsalo para detectar errores de escritura, nunca como tu única validación.