Pagamentos8 min de leitura

O algoritmo de Luhn: o que ele detecta, o que não detecta e por que ainda é usado

Como funciona o checksum que valida números de cartão, quais erros de digitação ele pega, quais passam despercebidos e por que passar no Luhn não significa que o cartão existe.

Publicado em

AL

Por André Leitão

Desenvolvedor de software

Quando você digita um número de cartão errado em um checkout bem-feito, a mensagem de erro aparece antes mesmo de o formulário ser enviado. Não há consulta ao banco, não há chamada ao adquirente — há uma conta de somar que existe desde os anos 1950 e continua fazendo o mesmo trabalho: detectar dígito digitado errado.

O algoritmo de Luhn é simples o bastante para ser feito de cabeça e é o motivo de a maioria dos erros de digitação de cartão nunca chegar ao processador de pagamento. Vale entender o que exatamente ele garante — e o que muita gente acha que ele garante e não é verdade.

Como o cálculo funciona

O procedimento tem quatro passos, aplicados sobre os dígitos do número da direita para a esquerda.

  1. 1Percorra os dígitos da direita para a esquerda, começando pelo último.
  2. 2Dobre o valor de cada dígito em posição par nessa contagem — ou seja, o segundo, o quarto, o sexto, e assim por diante.
  3. 3Se o resultado da duplicação passar de 9, subtraia 9. Isso equivale a somar os dois algarismos do produto.
  4. 4Some todos os valores. O número é válido pelo Luhn se a soma for múltiplo de 10.

Acompanhe com o número de teste 4539 1488 0343 6467, um dos exemplos mais citados em documentação de pagamento.

Aplicação do Luhn sobre os últimos oito dígitos
Posição (da direita)DígitoDobra?Valor somado
17Não7
26Sim → 12 → 12-93
34Não4
46Sim → 12 → 12-93
53Não3
64Sim → 88
73Não3
80Sim → 00

Continuando pelos oito dígitos restantes e somando tudo, chega-se a 80 — múltiplo de 10, portanto o número passa no Luhn.

Implementação em JavaScript
export function validarLuhn(entrada) {
  const digitos = String(entrada).replace(/\D/g, "");
  if (digitos.length < 12) return false;

  let soma = 0;
  let dobrar = false;

  // Da direita para a esquerda.
  for (let i = digitos.length - 1; i >= 0; i--) {
    let valor = digitos.charCodeAt(i) - 48;

    if (dobrar) {
      valor *= 2;
      if (valor > 9) valor -= 9;
    }

    soma += valor;
    dobrar = !dobrar;
  }

  return soma % 10 === 0;
}

O que o Luhn detecta e o que escapa

O algoritmo foi projetado para um problema específico: alguém digitando manualmente uma sequência longa de números. Ele acerta em cheio nesse cenário e é indiferente a outros.

Cobertura do algoritmo por tipo de erro
Tipo de erroExemploDetectado?
Um dígito trocado4539 → 4549Sempre
Transposição de adjacentes45 → 54Quase sempre
Transposição de 09 ou 9009 → 90Nunca
Dois dígitos trocados de uma vez4539 → 4629Às vezes
Dígito faltando ou sobrando16 → 15 dígitosQuase sempre, pelo tamanho

A linha do 09 e 90 é a limitação conhecida do algoritmo. Ela existe porque dobrar 0 dá 0 e dobrar 9 dá 18, que vira 9 depois da subtração — a troca não altera a soma. Nenhuma implementação corrige isso, porque a correção exigiria um algoritmo diferente.

O que o Luhn não é

Aqui mora a confusão que aparece em revisão de código e em conversa com produto.

  • Não é autenticação: não diz nada sobre quem digitou o número.
  • Não é verificação de existência: a esmagadora maioria dos números que passam no Luhn nunca foi emitida por ninguém.
  • Não é antifraude: um fraudador com um número real e válido passa no Luhn tão bem quanto um cliente legítimo.
  • Não é criptografia: não há segredo envolvido, e qualquer um calcula o dígito final de um número incompleto.

O único papel do Luhn é economizar uma ida ao adquirente quando o usuário errou uma tecla, e transformar a recusa genérica em uma mensagem útil no campo certo do formulário.

O que vem antes e depois do Luhn no checkout

Um formulário de pagamento bem construído aplica várias verificações em camadas, cada uma respondendo a uma pergunta diferente.

Camadas de verificação em um checkout
CamadaPerguntaOnde acontece
Tamanho e caracteresO campo tem o formato esperado?Cliente
Faixa do BINQual bandeira e que máscara aplicar?Cliente
LuhnHá erro de digitação?Cliente
AutorizaçãoO cartão existe, está ativo e tem limite?Adquirente e emissor
AntifraudeA transação é legítima?Motor de risco
Autenticação 3-D SecureO portador aprovou?Emissor

Números de teste e por que eles existem

Para testar máscara, detecção de bandeira, mensagens de erro e layout do formulário, é preciso de números que passem no Luhn. Usar um cartão real para isso é desnecessário e arriscado — inclusive porque o número acaba em captura de tela, em fixture versionada e em log de desenvolvimento.

O gerador de cartão do Codigio Labs monta números que satisfazem o Luhn a partir do prefixo da bandeira escolhida, inteiramente no navegador. Eles servem para exercitar a interface e a validação local, e não correspondem a nenhuma conta existente.

Resumo

  • O Luhn soma os dígitos dobrando um a cada dois da direita para a esquerda e exige que o total seja múltiplo de 10.
  • Detecta todo erro de um dígito e quase toda transposição adjacente, exceto 09 contra 90.
  • Passar no Luhn não indica existência, titularidade, saldo nem legitimidade.
  • Valide no cliente para dar feedback imediato e nunca armazene o número completo.
  • Para testar cobrança de verdade, use os cartões de teste do seu provedor.

Perguntas frequentes

Um número que passa no Luhn é um cartão válido?
Não. O Luhn é um checksum de digitação: ele só confirma que os dígitos são internamente consistentes. Não diz que o cartão foi emitido, que está ativo, que tem saldo nem a quem pertence. Essas respostas só vêm de uma autorização junto ao emissor.
Quais erros o Luhn detecta?
Todos os erros de um único dígito trocado e a maioria das transposições de dígitos adjacentes. Ele foi projetado exatamente para o cenário de alguém digitando um número longo e errando uma tecla.
Quais erros passam despercebidos?
A transposição de 09 para 90 e vice-versa é o caso clássico que o algoritmo não pega. Trocas envolvendo dígitos não adjacentes também podem passar. Por isso o Luhn reduz erros, mas não elimina a necessidade de o usuário conferir o número.
Devo validar o Luhn no meu checkout?
Sim, no cliente, como feedback imediato antes de enviar. Ele evita uma tentativa de autorização inútil e dá uma mensagem de erro melhor que a recusa genérica do adquirente. O que ele não pode fazer é substituir a autorização.
Posso usar números gerados para testar meu gateway?
Para testar a interface, a máscara e a validação local, sim. Para testar a cobrança de ponta a ponta, use os cartões de teste oficiais do seu provedor: eles disparam cenários específicos de aprovação, recusa e erro que um número qualquer não reproduz.

Ferramentas relacionadas

AL

Sobre o autor

Desenvolvedor de software no Brasil. Mantém o Codigio Labs desde a primeira ferramenta, escreve os artigos do site e revisa os textos quando a informação técnica muda.

Encontrou um erro ou tem uma correção a sugerir? Fale com o Codigio Labs. Correções relevantes são aplicadas com atualização da data de revisão do texto.

Continue lendo