Validace čísla účtu v PHP

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.

9 thoughts on “Validace čísla účtu v PHP”

  1. 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).

  2. 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.

  3. 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})$/‘

  4. 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) { …

Komentáře nejsou povoleny.