Como gerar um IBAN válido em código (Python, JS, PHP)

Como gerar um IBAN válido em código (Python, JS, PHP)

Um guia prático para gerar IBAN válidos e corretos segundo o MOD-97 por programação em Python, JavaScript e PHP, para dados de teste, dados de seed e pipelines de QA.

Escrito por David S · Publicado em 2026-05-26
#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 IBAN válidos para os testes e não há uma boa forma de os escrever à mão. Copiar e colar o mesmo punhado de exemplos gera conjuntos de testes frágeis, e usar um IBAN real é um problema de conformidade à espera de acontecer. A solução limpa é gerá-los por programação: estruturalmente corretos, com dígitos verificadores válidos e tantos quantos precisar.

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)])

Isto mantém o BBAN numérico por simplicidade, o que está correto para os países acima. Alguns países (o Reino Unido, por exemplo) incluem letras no código do banco; para esses, teria também de aleatorizar as posições das letras. Para dados de teste, um BBAN totalmente numérico costuma servir, pois continua a passar as verificações de MOD-97 e de comprimento.


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

O PHP precisa da extensão bcmath para o módulo do número grande, que vem incluída na maioria das instalações.

<?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 dados novos e válidos.
  • 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 são estruturalmente válidos e passam o MOD-97, mas não são contas reais e 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?

Sim, para testes, QA, demonstrações e documentação. São estruturalmente válidos e passam a validação da soma de verificação, mas não estão ligados a nenhuma conta bancária real. Nunca use IBAN gerados para transações reais nem num sistema de pagamentos em produção.

Preciso de uma biblioteca externa para gerar um IBAN?

Não. Os exemplos acima usam apenas a biblioteca padrão de cada linguagem: os inteiros grandes integrados do Python, um ciclo de resto acumulado em JavaScript e o bcmath incluído no PHP. As bibliotecas podem ajudar na cobertura completa de países, mas o algoritmo central são poucas linhas.

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 verifica um número 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 tornam o número válido. Partilham a mesma rotina central.

Experimente Nossas Ferramentas IBAN

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