Tento článek patří do seriálu Práce s čísly účtů. Ostatní články seriálu:
- Jak poznat správné číslo účtu
- Generování a kontrola IBANu pro CZ i SK účty
TL;DR Pokud vás zajímá pouze validace IBANu, použijte knihovnu PHP-IBAN. Ta ale neumí převádět běžná čísla českých a slovenských účtů na IBAN. Umí ale validovat IBAN všech zemí.
IBAN, z anglického International Bank Account Number, je mezinárodně dohodnutý systém pro identifikaci bankovních účtů. Původně vznikl pro potřeby Evropské Unie, nyní je ale rozšířen i do dalších zemí za hranice Evropy.
Formát a validace
Základní formát IBANu je v zásadě jednoduchý. Začíná 2 písmenným kódem země a dvojicí kontrolních číslic. Následuje část, která se skládá z alfanumerických znaků v maximální délce 30 znaků. Každá země si může určit vlastní formát, vždy ale musí být pevné délky. V Česku i na Slovensku to je 20 znaků, které začínají čtyřmístným kódem banky, následuje předčíslí a poté číslo účtu. Vždy doplněno nulami do délky 6 a 10 znaků. Celý IBAN má tedy délku 24 znaků.
Pro validaci se přesunou první 4 znaky (kód země a kontrolní číslice) na konec, znaky abecedy se přepíšou na čísla tak, že A -> 10, B -> 11 ... Z -> 35
. Poté se vypočte z tohoto velkého čísla zbytek po dělení 97, který se musí rovnat 1. Protože celé číslo se rozhodně nevleze do datového typu int
, je potřeba použít algoritmus založený na modulární aritmetice. Ukázka je níže.
Programový přístup – Kontrola
Pro kontrolu českého nebo slovenského IBANu lze použít kód níže. V PHP existuje rozšíření BC Math, které dokáže pracovat i s extrémně velkými čísly. A obsahuje funkci bcmod()
, která je v případě IBANu potřeba k výpočtu zbytku po dělení. V ukázce je ale i případná náhrada.
function replaceCharacters(string $toReplace): string { return str_replace(range('A', 'Z'), range(10, 35), $toReplace); } function validateIBAN(string $iban): bool { $iban = strtoupper($iban); if (!preg_match('/^((?:CZ|SK)[0-9]{2})([0-9]{20})$/', $iban, $matches)) { return false; } $rearrangeToNumber = replaceCharacters($matches[2].$matches[1]); return bcmod($rearrangeToNumber, '97') === '1'; // Vraci string } // Funkci bcmod() lze nahradit touto funkcí, pokud BCMath rozšíření není dostupné // nebo pokud se kód přepisuje do jiného jazyka function moduloHugeNumber(string $number, int $modulus): int { $remainder = 0; for ($i = 0; $i < strlen($number); $i++) { $remainder = ($remainder * 10 + ($number[$i] - '0')) % $modulus; } return $remainder; }
Regulární výraz lze nahradit za /^([A-Z]{2}[0-9]{2})([0-9A-Z]{11,30})$/
pro kontrolu správnosti IBANu i pro jiné země. Zde ale POZOR, již není kontrolována správná délka nebo kód země. Pouze správně vypočtené kontrolní číslo! Pro opravdovou kontrolu se všemi pravidly každé země je potřeba použít vhodnou knihovnu. Například PHP-IBAN.
Převody z/na národní čísla
Funkce níže dokáží převést české i slovenské národní číslo účtu na IBAN a obráceně. Při výpočtu jsou použity funkce validateIBAN()
a replaceCharacters()
z ukázky výše a také isValidBankAccount()
z předešlého článku Jak poznat správné číslo účtu.
Pokud je IBAN validní, neznamená to, že výsledné číslo účtu je také validní! IBAN v záhlaví je validní, ale číslo účtu v něm obsažené již ne. Kód banky neexistuje a jednotlivé části také nemohou existovat, viz předchozí článek o správném čísle účtu.
function ibanToNationalNumber(string $iban): ?string { if (!validateIBAN($iban) || !preg_match('/^(?:CZ|SK)[0-9]{2}([0-9]{4})([0-9]{6})([0-9]{10})$/', $iban, $matches)) { return null; } $prefix = ltrim($matches[2], '0'); return ($prefix ? $prefix.'-' : '').ltrim($matches[3], '0').'/'.$matches[1]; } function nationalNumberToIban(string $accNumber, string $countryCode = 'CZ'): ?string { if(!isValidBankAccount($accNumber) || !in_array($countryCode, ['CZ', 'SK']) || !preg_match('/^(?:([0-9]{2,6})-)?([0-9]{2,10})\/([0-9]{4})$/', $accNumber, $matches) ) { return null; } $bban = $matches[3].str_pad($matches[1], 6, '0', STR_PAD_LEFT).str_pad($matches[2], 10, '0', STR_PAD_LEFT); $remainder = (int)bcmod(replaceCharacters("{$bban}{$countryCode}00"), '97'); $controllNumber = str_pad((string)(98 - $remainder), 2, '0', STR_PAD_LEFT);
return "{$countryCode}{$controllNumber}{$bban}"; }
Pár dalších informací navíc o IBANu
- Celý identifikátor se nazývá IBAN, část bez kódu země a kontrolní číslice pak BBAN (Basic Bank Account Number).
- Více informací je samozřejmě jako vždy na Wikipedii, ať už české nebo anglické.
- O správu a registraci IBAN formátů pro jednotlivé země se stará belgická firma SWIFT. Ta má na svých stránkách PDF dokument s formáty všech možných IBAN formátů pro registrované země. Kromě jiného zde jsou i kontakty na národní banky všech zemí.
- Podle normy se u IBANu rozlišuje velikost písmen, při kontrole se ale vždy převedou na velká písmena. Co jsem ale dohledal, asi se to nikde neděje a IBAN je vždy převeden na velká písmena.
Zkušenosti s IBAN nebo čísly účtu můžete sdílet v komentářích.
K tomuto článku již není možné přidávat další komentáře