O algoritmo de Luhn explicado: como funciona a validação do número do cartão
Todo número de cartão que você já digitou em um formulário passou por um algoritmo de 70 anos antes de sair do seu navegador. O algoritmo de Luhn — também chamado de MOD 10 ou algoritmo módulo 10 — é a soma de verificação (checksum) que todas as principais bandeiras usam para detectar erros de digitação. Este guia explica como ele funciona, como implementá-lo e o que ele não consegue fazer.
O que é o algoritmo de Luhn?
O algoritmo de Luhn foi inventado pelo cientista da IBM Hans Peter Luhn em 1954 e patenteado em 1960. É uma fórmula simples de soma de verificação que detecta erros acidentais em números de identificação: erros de um único dígito, a maioria das trocas de dígitos adjacentes e algumas outras classes de erro.
Não é uma medida de segurança nem criptografia. É uma verificação de integridade de dados. As bandeiras acrescentam um dígito verificador de Luhn a cada número de cartão, e qualquer sistema pode verificá-lo com poucas linhas de código e sem acesso à rede.
Como funciona, passo a passo
Dado um número, por exemplo 79927398713:
- Começando pelo dígito mais à direita e avançando para a esquerda, dobre cada segundo dígito.
- Se a duplicação gerar um valor maior que 9, subtraia 9 (isso equivale a somar entre si os dois dígitos do resultado).
- Some todos os dígitos — tanto os dobrados quanto os que ficaram intactos.
- Se o total for divisível por 10, o número passa na verificação.
Para 79927398713, os dígitos processados somam 70, então o número é válido.
Em um cartão real, o dígito verificador não é conhecido de antemão: o emissor o calcula para que o número final passe na verificação. É por isso que todo número de cartão válido do mundo satisfaz a mesma condição de uma linha: total % 10 === 0.
Implementação
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;
}
Você pode testar qualquer número na hora com o nosso validador de Luhn.
O que o Luhn não detecta
O algoritmo de Luhn é deliberadamente simples, o que também o torna fácil de enganar:
- Não é capaz de dizer se um cartão existe. Qualquer número pode se tornar válido no Luhn, inclusive números de BINs que nunca foram emitidos. O Luhn não diz nada sobre a conta, o saldo ou o emissor.
-
Ele deixa passar algumas trocas de posição. Trocar
09por90produz a mesma soma, então essa troca específica não é detectada. A maioria das outras trocas de dígitos adjacentes é detectada. - Não valida o tamanho nem o BIN. As regras de tamanho e as faixas de BIN são verificações separadas. Um número de 16 dígitos pode passar no Luhn e ainda assim ser inválido para um BIN de Amex de 15 dígitos.
- Não é um recurso de segurança. Atacantes geram números válidos no Luhn com facilidade; a verificação existe para proteger os usuários de erros de digitação, não os sistemas contra fraudes.
Por que isso importa para os desenvolvedores
Se você constrói algo que aceita dados de cartão, vai encontrar o Luhn em pelo menos três lugares:
- Validação no lado do cliente: dê ao usuário um retorno instantâneo antes de enviar o formulário e evite uma ida e volta ao seu provedor de pagamentos por um erro de digitação óbvio.
- Geração de dados de teste: fixtures, seeds e scripts de QA precisam de números que passem na validação, o que significa calcular corretamente o dígito verificador. É exatamente o que o nosso gerador de cartões de teste faz.
- Análise e normalização: quando os números chegam de clientes, planilhas ou logs, o Luhn é a verificação básica mais barata antes de enviar qualquer coisa a um gateway de pagamento.
Como gerar números de teste válidos
Para gerar números de teste estruturalmente válidos a partir de qualquer BIN, use o gerador de cartões do Namso Gen. Ele calcula o dígito verificador de Luhn para você e pode adicionar datas de validade e CVVs. Se você quiser enumerar todas as combinações de um padrão, o gerador avançado aceita curingas x.
Para um passo a passo completo das verificações que vão além do Luhn, veja números BIN explicados ou consulte qualquer prefixo com o verificador de BIN.
Resumo
- O Luhn (MOD 10) é uma soma de verificação, não uma validação de existência nem um recurso de segurança.
- Dobrar cada segundo dígito da direita, somar e conferir se o total é divisível por 10 é tudo o que ele faz.
- Todas as principais bandeiras o usam, e é por isso que todo número de cartão real passa na verificação.
- Use-o para detectar erros de digitação, nunca como sua única validação.