Málokdo ví, že (podobně jako rodné číslo) i číslo účtu lze validovat na správnost pomocí modulo 11. Algoritmus je o něco složitější než v případě rodného čísla, ale není nijak složitý. Obecně je popsaný v tomto dokumentu na straně 49.
Úkolem je vytvořit validační funkci v PHP. Vstupem funkce bude jeden parametr – číslo účtu $bankAccount. Výstupem bude boolean hodnota TRUE nebo FALSE (TRUE pokud je číslo validní).
Číslo účtu může sestávat z předčíslí (max. 6 číslic) odděleného pomlčkou a z hlavní části (max. 10 číslic). Předčíslí (prefix) je nepovinné.
if(!preg_match('/(([0-9]{0,6})-)?([0-9]{1,10})/', $bankAccount, $matches)) { return FALSE; }
Do obou částí čísla účtu přidáme zleva leading zeroes. UPDATE: kvůli chybě popsané v komentářích jsem u druhé části místo sprintf funkce využil alterativní metodu:
$first = sprintf('%06d', $matches[1]); $second = str_repeat('0', 10-strlen($matches[3])) . $matches[3];
V první části přiřadíme jednotlivým číslicím váhy dle vyhlášky a spočítáme modulo 11:
$isOkFirst = (10 * $first[0] + 5 * $first[1] + 8 * $first[2] + 4 * $first[3] + 2 * $first[4] + 1 * $first[5]) % 11 == 0; if($isOkFirst === FALSE) { return FALSE; }
To samé provedeme s druhou částí:
$isOkSecond = ( 6*$second[0] + 3 * $second[1] + 7 * $second[2] + 9 * $second[3] +10 * $second[4] + 5 * $second[5] + 8 * $second[6] + 4 * $second[7] + 2 * $second[8] + 1 * $second[9]) % 11 == 0; if($isOkSecond == FALSE) { return FALSE; }
A konečně, pokud zadané číslo účtu prošlo sítem až sem, vrátíme TRUE.
return TRUE;
Celou funkci si můžete stáhnout zde.
ignoruje se kod banky, trochu jsem to zmenil:
if(!preg_match(‚~(([0-9]{0,6})-)?([0-9]{1,10})/[0-9]{4}~‘, $bankAccount, $matches)) {
return FALSE;
}
jinak to nekdo chtel zde:
https://webtrh.cz/297161-php-skript-overeni-platnosti-bankovniho
Děkuji. Zapomněl jsem dodat, že funkce předpokládá, že dostane jen číslo účtu (bez kódu banky) – v instanci, kde jsem tuto funkci použil totiž provádím samostatnou validaci čísla účtu a pak jinou validaci pro kód banky (výčtem možných hodnot).
Upozornění: funkce nemusí fungovat všude, pokud máte problémy, tak pravděpodobně sprinf(‚%010d%‘) narazil na PHP_INT_MAX což Vám z čísla účtu na 32bit SW/HW udělá 2147483647, což je naštěstí neplatné čislo účtu 🙂 🙂 :-).
Ač se to zdá jako nepravděpodobné, narazil jsem na tento problém u dvou různých „velkých“ poskytovatelů hostingu.
Díky za super funkci!
Problém při použití nastane, pokud uživatel vloží nějaký nepovolený znak až za číslo účtu.
Příklad:
„000000-0168540115“ – projde
„000000-0168540115..??..nevalidnistring._ahoj.“ – projde také
při upravení reguláru přídáním $ na konec by měl být problém vyřešen ‚/(([0-9]{0,6})-)?([0-9]{1,10})$/‘
MOc díky právě jsi mně moc pomohl
Na doplnění nul bych doporučil použít funkci str_pad.
Díky za funkci, ovšem je tam pár chyb:
Regulární výraz nemusí validovat celý řetězec, ale jen jeho část. Může tedy projít nesmysl, který obsahuje číslo účtu ale před ním i po něm jsou různé znaky. Je třeba to změnit na ‚/^(([0-9]{0,6})-)?([0-9]{1,10})$/‘
Dále jsem tápal, proč používáš na jednom místě striktně typové porovnávání na FALSE a u počítání druhého modula už ne. Každopádně nutné to není a lze to zkrátit na:
if(!$isOkFirst) { …
if(!$isOkSecond) { …
Super, toto jsem hledal. Díky moc.