METODOLOGIA · PADRÃO GLOBAL
IBAN: o Algoritmo MOD-97 (ISO 13616)
O IBAN é usado em transferências internacionais brasileiras via SWIFT. O algoritmo MOD-97, definido na ISO 13616, verifica erros em números de conta bancária internacionais. Esta página explica cada passo, inclui um exemplo com IBAN alemão real, e cobre 13 casos de borda de produção — incluindo por que BigInt é obrigatório no JavaScript.
O algoritmo
O IBAN (International Bank Account Number) segue a norma ISO 13616. O algoritmo de verificação é MOD-97. Um IBAN tem até 34 caracteres: código do país (2 letras) + dígitos de controle (2 dígitos) + BBAN (até 30 caracteres alfanuméricos).
No Brasil, o IBAN é exigido em transferências internacionais via SWIFT. Um IBAN com erro de digitação resulta em rejeição pelo banco receptor com custo de reembolso e taxa de retorno. Os passos do algoritmo:
- Mover os 4 primeiros caracteres para o final da string. Ex: DE89370400440532013000 → 370400440532013000DE89
- Substituir cada letra pelo equivalente numérico: A=10, B=11, … Z=35.
- Calcular a string numérica resultante mod 97. Se o resultado for 1, o IBAN é válido.
Exemplo numérico passo a passo
Verificamos o IBAN alemão DE89 3704 0044 0532 0130 00. O algoritmo é universal — funciona para qualquer IBAN, independentemente do país emissor.
DE89370400440532013000370400440532013000DE89370400440532013000138989370400440532013000138989 mod 97 = 1 ✓Pseudocódigo
iban = strip_spaces(input).toUpperCase()
if length < 15 OR length > 34 → INVALID
if iban[0..1] not alpha OR iban[2..3] not digits → INVALID
rearranged = iban[4..] + iban[0..3]
numeric_str = replace each letter C with (ord(C) − ord('A') + 10)
return to_bigint(numeric_str) mod 97 == 1Casos de borda que uma implementação simples não trata
- Comprimento fixo por país: cada país tem um comprimento IBAN fixo definido no registro ISO 13616-1. Alemanha: 22, Espanha: 24, Reino Unido: 22, Itália: 27, França: 27. Um IBAN que passa MOD-97 mas não respeita o comprimento do país é inválido.
- Espaços a cada 4 caracteres (formato imprimível): o formato legível inclui espaços (DE89 3704 0044 0532 0130 00). Devem ser removidos antes de validar. Strings com tabs ou newlines misturados aparecem em importações de arquivos.
- BigInt no JavaScript: o número resultante da conversão pode ter 68 dígitos. Number.MAX_SAFE_INTEGER tem 16 dígitos. Sem BigInt, mod 97 produzirá resultados incorretos para IBANs longos.
- Minúsculas ou mixed case: a ISO define o IBAN em maiúsculas. Inputs em minúsculas (de89...) ou mixed case devem ser normalizados. Alguns bancos os entregam em minúsculas nas suas APIs.
- Código de país inválido: MOD-97 pode passar para uma string com código de país inexistente no registro IBAN. Verificar o country code contra a lista ISO 3166-1 alpha-2 é um passo adicional necessário.
- Estrutura interna do BBAN varia por país: o BBAN tem estrutura interna (código do banco, agência, número de conta) que varia por país. MOD-97 passa se os dígitos estiverem corretos, mas a sub-estrutura pode ser inválida.
- IBAN válido ≠ conta ativa: MOD-97 verifica o checksum do formato, não que a conta exista, esteja ativa ou tenha saldo. Um IBAN com um dígito alterado que ainda passe MOD-97 pode apontar para uma conta de outra pessoa.
- Brasil não usa IBAN domesticamente: o Brasil usa IBAN apenas em transferências SWIFT internacionais. TED e PIX usam agência/conta ou chave PIX. Validar um número de conta doméstico brasileiro como IBAN é um erro de design.
- Argentina não usa IBAN: a Argentina usa CBU (22 dígitos) para transferências domésticas. Não há código AR no registro IBAN. Sistemas globais que assumem IBAN universal falham com contas argentinas.
- Países com IBAN não padronizado ou territórios offshore: alguns territórios emitem IBANs que passam MOD-97 mas não estão no registro oficial SWIFT. A lista de países válidos deve ser atualizada periodicamente.
- Caracteres Unicode invisíveis: copiar um IBAN de um PDF ou e-mail com caracteres de controle (zero-width space, soft hyphen) pode fazer com que o strip de espaços não remova todos os separadores não numéricos.
- Performance do módulo em strings longas: calcular mod 97 sobre um BigInt de 68 dígitos pode ser um gargalo ao validar milhões de IBANs. Chunking (calcular mod em grupos de dígitos) é mais eficiente.
- IBAN como campo opcional vs obrigatório: em sistemas de pagamentos internacionais, alguns fluxos aceitam IBAN ou SWIFT+número de conta alternativamente. Validar como IBAN um campo que pode ser qualquer um dos dois produz falsos negativos.
Quer pular tudo isso?
Tratar todos esses casos de borda em produção exige semanas de testes e manutenção contínua conforme as regras regulatórias mudam. A API da Normadata trata tudo isso — incluindo casos que nem listamos aqui — com uma única chamada REST.
Fontes
ISO 13616-1:2020 — International Bank Account Number (IBAN). SWIFT/ECBS IBAN Registry. O padrão é público e de livre acesso.