Como gerar IBANs de teste com checksum válido em código (Python, JS, PHP)

Como gerar IBANs de teste com checksum válido em código (Python, JS, PHP)

Guia prático para gerar valores IBAN sintéticos corretos segundo o MOD-97 em Python, JavaScript e PHP, explicitando os limites dos padrões nacionais.

Escrito por David S · Publicado em 2026-05-26 · Atualizado em 2026-07-18
#generate IBAN #IBAN in code #Python IBAN #JavaScript IBAN #PHP IBAN #test data #MOD-97 #fixtures

A certa altura, a maioria de quem desenvolve sistemas de pagamento esbarra na mesma parede: precisa de valores com formato IBAN e checksum válido para os testes. Copiar e colar o mesmo punhado de exemplos gera conjuntos frágeis, e usar dados de contas de clientes cria riscos desnecessários de privacidade e operação. Uma abordagem mais segura é gerar valores sintéticos e mantê-los isolados dos sistemas de pagamento reais.

Este guia mostra exatamente como fazê-lo em Python, JavaScript e PHP. No fim terá uma função pequena e com poucas dependências que pode incorporar numa factory, num script de seed ou num módulo de fixtures. Se só precisar de alguns números agora mesmo sem escrever código, o gerador Random IBAN produ-los instantaneamente e exporta para CSV, JSON ou TXT.


O que «gerar um IBAN» significa realmente

Um IBAN não é um único número opaco: são três partes concatenadas.

ES 76 21000418450200051332
│  │  └── BBAN (country-specific: bank + branch + account)
│  └───── Check digits (calculated, positions 3–4)
└──────── Country code (ISO 3166-1, positions 1–2)

Por isso, gerá-lo significa fazer três coisas por ordem:

  1. Escolher um país e consultar o comprimento do seu IBAN e a disposição do seu BBAN.
  2. Construir um BBAN aleatório que corresponda a essa disposição (o número correto de dígitos, e letras onde a especificação as permitir).
  3. Calcular os dois dígitos verificadores com o algoritmo MOD-97 para que o conjunto seja válido.

O primeiro passo precisa de uma pequena tabela de consulta. O segundo é pura geração aleatória. O terceiro é a única parte com lógica real, e é a mesma rotina que usaria para validar um IBAN, executada ao contrário.


O essencial: calcular os dígitos verificadores

Todas as linguagens abaixo partilham a mesma rotina de dígitos verificadores. A regra das normas ISO 7064 / ISO 13616 é:

  1. Tome o BBAN, acrescente o código do país e depois acrescente 00.
  2. Substitua cada letra por dois dígitos (A=10, B=11, … Z=35).
  3. Leia o resultado como um único inteiro grande e calcule 98 - (inteiro mod 97).
  4. Complete esse resultado com zeros até dois dígitos.

Esse número completado é o seu par de dígitos verificadores. Coloque-o entre o código do país e o BBAN, e o IBAN final passará na validação MOD-97. Vamos implementá-lo.


Gerar um IBAN em Python

Os inteiros de precisão arbitrária do Python tornam isto quase trivial: não é necessária qualquer biblioteca de inteiros grandes.

import random

# Minimal layout table: country -> (total length, BBAN length)
IBAN_SPECS = {
    "DE": 22, "ES": 24, "FR": 27, "GB": 22,
    "NL": 18, "IT": 27, "PT": 25, "BE": 16,
}

def _check_digits(country: str, bban: str) -> str:
    rearranged = bban + country + "00"
    numeric = "".join(
        str(ord(c) - 55) if c.isalpha() else c
        for c in rearranged
    )
    check = 98 - (int(numeric) % 97)
    return f"{check:02d}"

def generate_iban(country: str = "ES") -> str:
    total_len = IBAN_SPECS[country]
    bban_len = total_len - 4            # minus country code + check digits
    bban = "".join(random.choices("0123456789", k=bban_len))
    return country + _check_digits(country, bban) + bban

# Usage
print(generate_iban("DE"))   # e.g. DE21 ... (valid checksum)
print([generate_iban("ES") for _ in range(5)])

Este exemplo mínimo só modela o comprimento total e o MOD-97. O seu BBAN numérico não cumpre o padrão nacional nem os controlos internos de todos os países da tabela (Reino Unido, Países Baixos e Itália exigem letras em posições específicas, por exemplo), e um identificador bancário aleatório pode não estar atribuído nem atual. Trate o resultado como um exercício de checksum. Para fixtures com formato nacional, implemente o padrão completo do registo SWIFT e os controlos internos, ou use a RandomIBAN com os respetivos limites documentados.


Gerar um IBAN em JavaScript

Em JS, o único senão é que o número reordenado é demasiado grande para um Number normal. A solução padrão é um ciclo de resto acumulado, que mantém o valor abaixo de 97 o tempo todo.

const IBAN_SPECS = {
  DE: 22, ES: 24, FR: 27, GB: 22,
  NL: 18, IT: 27, PT: 25, BE: 16,
};

function mod97(numericString) {
  let remainder = 0;
  for (const ch of numericString) {
    remainder = (remainder * 10 + Number(ch)) % 97;
  }
  return remainder;
}

function checkDigits(country, bban) {
  const rearranged = bban + country + '00';
  const numeric = rearranged.replace(/[A-Z]/g, c =>
    (c.charCodeAt(0) - 55).toString()
  );
  const check = 98 - mod97(numeric);
  return String(check).padStart(2, '0');
}

function generateIban(country = 'ES') {
  const bbanLen = IBAN_SPECS[country] - 4;
  let bban = '';
  for (let i = 0; i < bbanLen; i++) {
    bban += Math.floor(Math.random() * 10);
  }
  return country + checkDigits(country, bban) + bban;
}

// Usage
console.log(generateIban('FR'));
console.log(Array.from({ length: 5 }, () => generateIban('NL')));

Se precisar de uma aleatoriedade criptograficamente mais robusta (raramente necessário para dados de teste), troque Math.random() por crypto.getRandomValues(). Para fixtures e demonstrações, a versão simples é perfeitamente adequada.


Gerar um IBAN em PHP

Este exemplo em PHP precisa da extensão opcional bcmath para o módulo do número grande. Confirme que está instalada e ativada no ambiente onde executa o código.

<?php
const IBAN_SPECS = [
    'DE' => 22, 'ES' => 24, 'FR' => 27, 'GB' => 22,
    'NL' => 18, 'IT' => 27, 'PT' => 25, 'BE' => 16,
];

function checkDigits(string $country, string $bban): string {
    $rearranged = $bban . $country . '00';
    $numeric = '';
    foreach (str_split($rearranged) as $ch) {
        $numeric .= ctype_alpha($ch) ? (string)(ord($ch) - 55) : $ch;
    }
    $check = 98 - (int) bcmod($numeric, '97');
    return str_pad((string) $check, 2, '0', STR_PAD_LEFT);
}

function generateIban(string $country = 'ES'): string {
    $bbanLen = IBAN_SPECS[$country] - 4;
    $bban = '';
    for ($i = 0; $i < $bbanLen; $i++) {
        $bban .= random_int(0, 9);
    }
    return $country . checkDigits($country, $bban) . $bban;
}

// Usage
echo generateIban('IT'), PHP_EOL;

Repare no uso de random_int() em vez de rand(): é a opção moderna e sem enviesamento, e aqui não custa nada de extra.


Usar IBAN gerados num conjunto de testes

Assim que tiver um gerador, ligue-o aos seus testes em vez de espalhar literais. Alguns padrões que funcionam bem:

  • Factories e fixtures. Chame generateIban() dentro da sua factory (FactoryBoy, um provider do Faker, uma factory do Laravel) para que cada execução de testes obtenha fixtures novos que passam o checksum.
  • Dados de seed para staging. Preencha as bases de dados de demonstração com algumas centenas de IBAN de vários países para exercitar a formatação específica de cada um.
  • Casos-limite. Mantenha um conjunto à parte de cadeias deliberadamente inválidas (comprimento errado, dígito verificador incorreto, país não suportado) para verificar que a sua validação as rejeita.
  • Determinismo quando precisar. Defina a semente do seu gerador aleatório no início de um teste se quiser IBAN reproduzíveis; deixe-a indefinida para uma cobertura do tipo fuzzing.

Seja o que for que gere, rotule-o claramente como sintético. Estes números podem passar as verificações configuradas de estrutura e MOD-97, mas a RandomIBAN não verifica se um valor gerado coincide com uma conta atribuída. Nunca devem chegar a um sistema de pagamentos em produção. Consulte o nosso guia sobre como armazenar IBAN com segurança em sistemas de pagamento para evitar que os dados de teste e de produção se misturem.


Quando não escrever o seu próprio gerador

Criar o seu é ótimo para uma integração estreita, mas nem sempre compensa. Dispense o código quando:

  • Precisar de um lote rápido agora mesmo: cole-os em segundos a partir do gerador Random IBAN e exporte para CSV/JSON.
  • Precisar de ampla cobertura de países com subestruturas de BBAN corretas (dígitos verificadores nacionais, posições das letras) que uma tabela mínima não capta.
  • Estiver a trabalhar fora de uma base de código: a preparar uma folha de cálculo, uma coleção do Postman ou documentação.

E seja qual for o caminho que escolher, valide o resultado. Passe uma amostra pelo validador de IBAN para confirmar que a sua lógica de dígitos verificadores corresponde à implementação de referência. Se algo falhar o MOD-97, o erro está quase sempre na conversão de letras para números ou num erro de deslocamento de um (off-by-one) no comprimento do BBAN.


FAQ

É seguro usar IBAN gerados por programação?

São adequados para validação de formato isolada, QA, demonstrações e documentação se forem claramente identificados e bloqueados antes de qualquer circuito de pagamento real. Passar nas verificações de estrutura e checksum não prova que um valor não esteja atribuído; nunca o envie numa transação real nem para um sistema de produção.

Preciso de uma biblioteca externa para gerar um IBAN?

Os exemplos de Python e JavaScript não precisam de pacotes externos. O exemplo de PHP requer que a extensão opcional bcmath esteja instalada e ativada. Uma biblioteca especializada ou regras nacionais adicionais podem continuar a ser úteis se precisar de padrões BBAN completos, e não apenas do comprimento e do MOD-97.

Porque é que o meu IBAN gerado falha a validação?

As causas mais comuns são uma conversão incorreta de letras para números (tem de ir de A=10 a Z=35), esquecer-se de acrescentar o código do país e 00 antes do passo do módulo, ou usar um comprimento de BBAN errado para o país. Compare um único caso que falhe com o validador para o isolar.

Como gero IBAN para países com letras no BBAN?

Estenda o passo do BBAN aleatório para colocar letras onde a especificação do país as permitir — por exemplo, o código do banco do Reino Unido tem quatro letras. Mantenha um padrão por país (que posições são letras e quais são dígitos) em vez de um único comprimento, e depois preencha cada posição em conformidade antes de calcular os dígitos verificadores.

Posso gerar milhares de IBAN de uma vez?

Sim. As funções geradoras são baratas de chamar num ciclo, por isso produzir milhares é instantâneo. Se preferir não executar código, o gerador Random IBAN suporta a geração em massa e a exportação com um clique para CSV, JSON e TXT.

Qual é a diferença entre gerar e validar um IBAN?

A validação do checksum testa um valor existente confirmando que mod 97 == 1. A geração executa a mesma aritmética ao contrário: constrói primeiro o BBAN e depois calcula 98 - (mod 97) para encontrar os dígitos verificadores que fazem o valor passar no MOD-97. Partilham a mesma rotina central; nenhum dos passos prova que o BBAN nacional está completo nem que existe uma conta.

Experimente Nossas Ferramentas IBAN

Coloque seu conhecimento em prática com nossas ferramentas gratuitas.