Cada número de conta bancária internacional (IBAN) carrega dois pequenos dígitos que realizam um trabalho surpreendentemente importante. Ficam logo após o código do país — nas posições três e quatro — e são o detetor de erros incorporado do IBAN. Erre um único dígito e, na maioria das vezes, esses dois dígitos deixam de bater certo. Um formulário pode então recusar o valor antes do envio; o checksum, por si só, não decide se um banco processa um pagamento.
Este guia explica como esses dígitos verificadores são calculados, por que o passo do módulo 97 é tão eficaz e como calculá-los ou verificá-los de forma fiável nos seus próprios sistemas.
O que são realmente os dígitos verificadores do IBAN
Os dois dígitos que se seguem ao código do país chamam-se formalmente dígitos verificadores. Não são aleatórios nem fazem parte do seu número de conta: são derivados do resto do IBAN através de uma fórmula matemática definida na norma ISO 7064 (a mesma família de normas por detrás de muitos outros esquemas de dígitos verificadores).
O objetivo é a integridade. Quando um cliente digita um IBAN num formulário de pagamento, os dedos escorregam: um 3 torna-se um 8, dois dígitos vizinhos trocam de lugar, um carácter é omitido. Os dígitos verificadores permitem que qualquer banco — ou o seu próprio código de validação — detete esses erros de imediato, sem contactar o banco de destino.
Pense nisso como um bit de paridade a uma escala muito maior: uma impressão digital compacta da referência da conta, que viaja juntamente com os dados que protege.
Como funciona o cálculo dos dígitos verificadores
A rotina de validação é enganadoramente simples. Tome um IBAN francês como FR76 3000 6000 0112 3456 7890 189. Para o verificar:
- Mova os quatro primeiros caracteres para o fim.
FR76passa para o final, ficando30006000011234567890189FR76. - Substitua cada letra por dois dígitos. Cada letra corresponde a um número:
A=10,B=11, …Z=35. Assim,F=15eR=27, transformandoFR76em152776. - Leia o resultado como um único inteiro grande e calcule
inteiro mod 97. - Se o resto for exatamente 1, o valor passa no checksum do IBAN. Qualquer outro resto faz falhar a verificação. Um resto de 1 não verifica o código bancário nacional, a atribuição, a titularidade ou a acessibilidade da conta.
É esse todo o algoritmo. A genialidade está no passo 4: os dígitos verificadores são escolhidos, no momento em que o IBAN é criado, precisamente para que esse resto dê 1.
Calcular os dígitos verificadores do zero
Gerar um IBAN novo executa o processo ao contrário:
- Monte o BBAN (o código do banco, o balcão e o número de conta específicos de cada país).
- Acrescente o código do país seguido de
00como marcador de posição dos dígitos verificadores. - Converta as letras em números e calcule o inteiro grande.
- Calcule
98 - (inteiro mod 97). - Complete o resultado com zeros até dois dígitos — esse é o seu par de dígitos verificadores.
Por exemplo, calcular os dígitos verificadores do BBAN em formato alemão de DE89 3704 0044 0532 0130 00 produz 89. O gerador Random IBAN segue o padrão de caracteres configurado para cada país e deriva os dígitos para passar no MOD-97. As listas selecionadas de códigos bancários e os controlos nacionais só são usados onde estão implementados; a atualidade e a atribuição da conta não são verificadas.
Porquê módulo 97 (e não algo mais simples)?
Os criadores poderiam ter usado uma soma de verificação básica, do tipo «somar todos os dígitos». Escolheram o módulo 97 de forma deliberada, e essa escolha tem consequências reais para a fiabilidade.
- 97 é primo. Usar um módulo primo distribui os erros de forma uniforme e evita os pontos cegos que afetam os esquemas com módulos não primos.
- Deteta qualquer erro num único dígito. Altere um dígito qualquer e o resto muda — garantidamente.
- Deteta quase todas as transposições. Trocar dois caracteres vizinhos (um erro de digitação clássico) é detetado na esmagadora maioria dos casos.
- Num modelo simples de erros uniformemente aleatórios, um valor incorreto é aceite com uma probabilidade de 1/97, o que corresponde a uma taxa de deteção estimada de 98,97 %. Os padrões reais de erros de digitação podem ser diferentes, mas esta taxa continua muito acima da de uma simples soma ou de um único dígito verificador.
A contrapartida é que precisa de aritmética de inteiros grandes, porque um IBAN de 34 caracteres expande-se até um número com dezenas de dígitos. Na prática, isto não é problema: todas as linguagens comuns lidam com isso de forma nativa ou com uma biblioteca de uma única linha, e existe um truque por blocos (mais abaixo) que evita por completo os inteiros grandes.
Calcular os dígitos verificadores em código
Raramente precisa de um tipo inteiro grande. Pela forma como funciona a aritmética modular, pode processar o IBAN em pequenos blocos mantendo um resto acumulado. Esta é a abordagem canónica em várias linguagens.
JavaScript:
function isValidIban(iban) {
const s = iban.replace(/\s+/g, '').toUpperCase();
// Move first 4 chars to the end
const rearranged = s.slice(4) + s.slice(0, 4);
// Convert letters to numbers (A=10 ... Z=35)
const numeric = rearranged.replace(/[A-Z]/g, ch =>
(ch.charCodeAt(0) - 55).toString()
);
// Piece-wise mod 97 to avoid BigInt
let remainder = 0;
for (const digit of numeric) {
remainder = (remainder * 10 + Number(digit)) % 97;
}
return remainder === 1;
}
Python:
def is_valid_iban(iban: str) -> bool:
s = "".join(iban.split()).upper()
rearranged = s[4:] + s[:4]
numeric = "".join(
str(ord(c) - 55) if c.isalpha() else c
for c in rearranged
)
return int(numeric) % 97 == 1 # Python ints are arbitrary-precision
PHP:
function isValidIban(string $iban): bool {
$s = strtoupper(preg_replace('/\s+/', '', $iban));
$rearranged = substr($s, 4) . substr($s, 0, 4);
$numeric = '';
foreach (str_split($rearranged) as $ch) {
$numeric .= ctype_alpha($ch) ? (string)(ord($ch) - 55) : $ch;
}
// bcmod handles the large integer safely
return bcmod($numeric, '97') === '1';
}
As três seguem os mesmos quatro passos. A única diferença real está em como cada linguagem lida com o número grande: o Python usa inteiros grandes nativos, o PHP apoia-se em bcmod e o JavaScript contorna o problema com o ciclo de resto acumulado.
Valide cedo, valide duas vezes
Detetar um IBAN incorreto no momento certo poupa problemas a toda a gente. Algumas práticas que compensam de forma consistente:
- Valide primeiro no lado do cliente. Execute a verificação MOD-97 no navegador enquanto o utilizador escreve ou ao perder o foco, para que corrija o erro de imediato em vez de o fazer depois de submeter.
- Revalide no servidor. Nunca confie apenas no cliente: repita a verificação no backend para se proteger contra manipulações e pedidos automatizados.
- Normalize antes de verificar. Remova os espaços, passe tudo para maiúsculas e rejeite os caracteres fora de
A–Ze0–9antes de executar o algoritmo. - Separe os erros de formato dos erros de dígitos verificadores nas suas mensagens. «Este IBAN é demasiado curto para a Alemanha» é muito mais útil para um cliente do que um genérico «IBAN inválido».
Lembre-se do limite dos dígitos verificadores: confirmam que o valor é internamente coerente segundo o MOD-97, não que a conta exista. Um IBAN com checksum válido pode mesmo assim apontar para uma conta encerrada ou inexistente. Para isso, precisa da verificação da conta junto do banco ou de um serviço dedicado.
Gerar IBAN de teste com dígitos verificadores válidos
Codificar um único IBAN no seu conjunto de testes é frágil, e usar um real é um risco de conformidade. Em vez disso, gere IBAN sintéticos com dígitos verificadores válidos a pedido.
Quando cria números com o Random IBAN, cada valor é construído com o método ISO/IEC 7064 MOD97-10 para os dígitos verificadores e a estrutura definida pela ISO 13616-1, pelo que passa nessa camada de verificação. Uma biblioteca que também verifique diretórios bancários atuais, regras do fornecedor ou controlos nacionais não implementados pode rejeitá-lo. Use-os para:
- Testar unitariamente as suas funções de validação com entradas válidas e inválidas conhecidas.
- Fazer QA de importações em massa exportando centenas de IBAN para CSV ou JSON.
- Demonstrar percursos de formulários de pagamento com entradas sintéticas bloqueadas antes de qualquer circuito de pagamento real.
Combine-o com o validador de IBAN para confirmar que a sua própria implementação coincide com o algoritmo de referência, e volte a verificar os seus dados de teste sempre que um país atualizar o seu formato de IBAN. Para mais contexto sobre a própria norma, consulte o nosso guia sobre o que é um número IBAN.
FAQ
Porque há sempre exatamente dois dígitos verificadores?
A norma do IBAN fixa o campo dos dígitos verificadores em dois dígitos para todos os países, independentemente do comprimento total. Dois dígitos dão 100 valores possíveis, suficientes para satisfazer o requisito do módulo 97 (os restos vão de 0 a 96) mantendo o formato compacto e uniforme em todo o mundo.
Pode um IBAN errado passar mesmo assim na verificação MOD-97?
Sim, embora seja improvável. Num modelo simples de erros uniformemente aleatórios, um valor incorreto é aceite com uma probabilidade de 1/97, o que corresponde a uma taxa de deteção estimada de 98,97 %. Os padrões reais de erros de digitação podem ser diferentes e uma pequena fração dos erros em vários caracteres pode, por coincidência, produzir um resto de 1. A verificação garante a estrutura, não que a conta seja real ou correta.
Qual é a diferença entre os dígitos verificadores e os dígitos verificadores nacionais?
Os dois dígitos verificadores do IBAN (posições 3 e 4) protegem todo o IBAN através do MOD-97. Alguns países — Espanha, França, Itália e outros — incorporam também os seus próprios dígitos verificadores nacionais dentro do BBAN para proteger o número de conta nacional. São mecanismos distintos que operam em camadas diferentes.
Preciso de uma biblioteca de inteiros grandes para validar um IBAN?
Não necessariamente. O método do resto por blocos mostrado acima processa o número em pequenos passos mantendo um valor acumulado abaixo de 97, pelo que basta aritmética de inteiros normal. Só precisa de inteiros grandes se calcular int(numeric) % 97 de uma só vez, como faz o exemplo em Python.
Porque é que a conversão das letras usa A=10 em vez de A=1?
Cada letra expande-se para um número de dois dígitos, de 10 a 35. Começar em 10 (em vez de 1) garante que cada letra corresponde a exatamente dois dígitos, o que mantém coerente a aritmética posicional. Se A fosse 1, as letras produziriam uma mistura de valores de um e dois dígitos e o cálculo falharia.
Como gero um IBAN com dígitos verificadores válidos para testes?
Use o gerador Random IBAN: escolha um país; a ferramenta preenche o padrão BBAN configurado e calcula os dígitos verificadores. Cada resultado passa no MOD-97, mas não são verificadas a atualidade do código bancário, a atribuição da conta nem a compatibilidade com um sandbox. Mantenha os valores isolados de sistemas de pagamento reais, pois uma coincidência acidental é possível.