À un moment ou à un autre, la plupart des personnes qui développent des systèmes de paiement se heurtent au même mur : il leur faut des valeurs au format IBAN avec un checksum valide pour les tests. Copier-coller la même poignée d’exemples produit des suites fragiles, et utiliser des données de compte client crée des risques inutiles de confidentialité et d’exploitation. Une approche plus sûre consiste à générer des valeurs synthétiques et à les isoler des systèmes de paiement réels.
Ce guide explique précisément comment procéder en Python, JavaScript et PHP. À la fin, vous disposerez d’une petite fonction à faibles dépendances que vous pourrez intégrer à une factory, à un script de données de départ ou à un module de fixtures. S’il vous faut seulement quelques numéros tout de suite sans écrire de code, le générateur Random IBAN les produit instantanément et les exporte au format CSV, JSON ou TXT.
Ce que « générer un IBAN » signifie réellement
Un IBAN n’est pas un unique nombre opaque : ce sont trois parties concaténées.
ES 76 21000418450200051332
│ │ └── BBAN (country-specific: bank + branch + account)
│ └───── Check digits (calculated, positions 3–4)
└──────── Country code (ISO 3166-1, positions 1–2)
Le générer revient donc à faire trois choses dans l’ordre :
- Choisir un pays et consulter la longueur de son IBAN et la disposition de son BBAN.
- Construire un BBAN aléatoire conforme à cette disposition (le bon nombre de chiffres, et des lettres là où la spécification les autorise).
- Calculer les deux chiffres de contrôle avec l’algorithme MOD-97 pour que l’ensemble soit valide.
La première étape nécessite une petite table de correspondance. La deuxième relève de la simple génération aléatoire. La troisième est la seule partie comportant une véritable logique, et c’est la même routine que celle utilisée pour valider un IBAN, exécutée à l’envers.
Le cœur du sujet : calculer les chiffres de contrôle
Tous les langages ci-dessous partagent la même routine de chiffres de contrôle. La règle issue des normes ISO 7064 / ISO 13616 est la suivante :
- Prenez le BBAN, ajoutez le code pays, puis ajoutez
00. - Remplacez chaque lettre par deux chiffres (
A=10,B=11, …Z=35). - Lisez le résultat comme un seul grand entier et calculez
98 - (entier mod 97). - Complétez ce résultat par des zéros sur deux chiffres.
Ce nombre complété est votre paire de chiffres de contrôle. Insérez-la entre le code pays et le BBAN, et l’IBAN ainsi obtenu passera la validation MOD-97. Passons à l’implémentation.
Générer un IBAN en Python
Les entiers à précision arbitraire de Python rendent l’exercice presque trivial : aucune bibliothèque de grands entiers n’est nécessaire.
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)])
Cet exemple volontairement minimal ne modélise que la longueur totale et MOD-97. Son BBAN numérique ne respecte pas le modèle national ni les contrôles internes de tous les pays du tableau (le Royaume-Uni, les Pays-Bas et l’Italie exigent notamment des lettres à des positions précises), et un identifiant bancaire aléatoire n’est pas forcément attribué ou actuel. Considérez le résultat comme un exercice de checksum. Pour des fixtures au format national, implémentez le modèle complet du registre SWIFT et les contrôles internes, ou utilisez RandomIBAN avec ses limites documentées.
Générer un IBAN en JavaScript
En JS, la seule difficulté est que le nombre réorganisé est trop grand pour un Number ordinaire. La solution standard est une boucle de reste courant, qui maintient la valeur en dessous de 97 en permanence.
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')));
Si vous avez besoin d’un aléa cryptographiquement plus robuste (rarement nécessaire pour des jeux de test), remplacez Math.random() par crypto.getRandomValues(). Pour des fixtures et des démonstrations, la version simple est parfaitement adéquate.
Générer un IBAN en PHP
Cet exemple PHP nécessite l’extension facultative bcmath pour le modulo du grand nombre. Vérifiez qu’elle est installée et activée dans l’environnement d’exécution.
<?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;
Notez l’usage de random_int() plutôt que rand() : c’est le choix moderne et non biaisé, et il ne coûte rien de plus ici.
Utiliser des IBAN générés dans une suite de tests
Une fois que vous disposez d’un générateur, intégrez-le à vos tests au lieu de disséminer des littéraux. Quelques approches qui fonctionnent bien :
- Factories et fixtures. Appelez
generateIban()à l’intérieur de votre factory (FactoryBoy, un fournisseur Faker, une factory Laravel) pour que chaque exécution de tests obtienne de nouvelles fixtures qui passent le checksum. - Données de départ pour la préproduction. Remplissez les bases de démonstration avec quelques centaines d’IBAN de plusieurs pays afin d’éprouver le formatage propre à chacun.
- Cas limites. Conservez un ensemble séparé de chaînes délibérément erronées (mauvaise longueur, chiffre de contrôle incorrect, pays non pris en charge) pour vérifier que votre validation les rejette.
- Déterminisme au besoin. Initialisez le germe de votre générateur aléatoire au début d’un test si vous voulez des IBAN reproductibles ; laissez-le non initialisé pour une couverture de type fuzzing.
Quoi que vous génériez, étiquetez-le clairement comme synthétique. Ces numéros peuvent passer les contrôles configurés de structure et MOD-97, mais RandomIBAN ne vérifie pas si une valeur générée coïncide avec un compte attribué. Ils ne doivent jamais atteindre un circuit de paiement en production. Consultez notre guide sur comment stocker les IBAN en toute sécurité dans les systèmes de paiement pour empêcher le mélange des données de test et de production.
Quand ne pas écrire son propre générateur
Développer le vôtre est excellent pour une intégration étroite, mais cela n’en vaut pas toujours la peine. Faites l’impasse sur le code lorsque :
- Il vous faut un lot rapide tout de suite : collez-les en quelques secondes depuis le générateur Random IBAN et exportez-les en CSV/JSON.
- Il vous faut une large couverture de pays avec des sous-structures de BBAN correctes (chiffres de contrôle nationaux, positions des lettres) qu’une table minimale ne capture pas.
- Vous travaillez en dehors d’une base de code : préparation d’un tableur, d’une collection Postman ou de documentation.
Et quelle que soit la voie choisie, validez le résultat. Faites passer un échantillon par le validateur d’IBAN pour confirmer que votre logique de chiffres de contrôle correspond à l’implémentation de référence. Si quelque chose échoue au MOD-97, le bug se trouve presque toujours dans la conversion des lettres en chiffres ou dans une erreur d’indice (off-by-one) sur la longueur du BBAN.
FAQ
Les IBAN générés par programmation sont-ils sûrs à utiliser ?
Ils conviennent à la validation de format isolée, à la QA, aux démonstrations et à la documentation s’ils sont clairement étiquetés et bloqués avant tout circuit de paiement réel. Réussir les contrôles de structure et de checksum ne prouve pas qu’une valeur n’est pas attribuée ; ne l’envoyez jamais dans une transaction réelle ni dans un système de production.
Ai-je besoin d’une bibliothèque externe pour générer un IBAN ?
Les exemples Python et JavaScript ne nécessitent aucun paquet externe. L’exemple PHP requiert que l’extension facultative bcmath soit installée et activée. Une bibliothèque spécialisée ou des règles nationales supplémentaires peuvent rester utiles si vous avez besoin de motifs BBAN complets, et pas seulement de la longueur et du MOD-97.
Pourquoi mon IBAN généré échoue-t-il à la validation ?
Les causes les plus fréquentes sont une conversion incorrecte des lettres en chiffres (elle doit aller de A=10 à Z=35), l’oubli d’ajouter le code pays et 00 avant l’étape du modulo, ou l’utilisation d’une mauvaise longueur de BBAN pour le pays. Comparez un seul cas en échec au validateur pour l’isoler.
Comment générer des IBAN pour les pays comportant des lettres dans le BBAN ?
Étendez l’étape de BBAN aléatoire pour placer des lettres là où la spécification du pays les autorise — par exemple, le code banque du Royaume-Uni compte quatre lettres. Conservez un motif par pays (quelles positions sont des lettres plutôt que des chiffres) au lieu d’une simple longueur, puis remplissez chaque position en conséquence avant de calculer les chiffres de contrôle.
Puis-je générer des milliers d’IBAN à la fois ?
Oui. Les fonctions de génération sont peu coûteuses à appeler dans une boucle, si bien qu’en produire des milliers est instantané. Si vous préférez ne pas exécuter de code, le générateur Random IBAN prend en charge la génération en masse et l’export en un clic vers CSV, JSON et TXT.
Quelle est la différence entre générer et valider un IBAN ?
La validation du checksum teste une valeur existante en confirmant que mod 97 == 1. La génération exécute la même arithmétique à l’envers : vous construisez d’abord le BBAN, puis vous calculez 98 - (mod 97) pour trouver les chiffres de contrôle qui font passer le MOD-97. Elles partagent la même routine centrale ; aucune des deux étapes ne prouve que le BBAN national est complet ni qu’un compte existe.