IČ - dříve IČO - je číslo jedinečně identifikující ekonomický subjekt, tedy podnikatele, firmu, sdružení, instituci apod. Jak ale zjistit, jestli má IČ správný formát?
Mnoho lidí ví, že IČ je číslo a tak spousta webů kontroluje IČ nějak takto:
function validIc($ic) {
return ctype_digit($ic);
}
Toto je sice dobře vypadající fce, ale projde ji i např. 123 nebo 123456789000, což platné IČ nejsou. Není těžké dohledat, že IČ platné v ČR má krom své číselné podoby maximální délku 8 znaků. Na wikipedii se píše, že IČ je přesně osmimístné, ale existují i kratší. Např. ministerstvo financí ma IČ 6947. Jak je tento rozpor možný? On to ani rozpor není, protože MF má ve skutečnosti IČ 00006947 a má tedy skutečně 8 míst. Úvodní nuly je ale přípustné vynechávat. Upravená funkce pro kontrolu IČ by tedy mohla vypadat následovně:
function validIc($ic) {
return ctype_digit($ic) && $ic < 100000000;
}
Touto úpravou odstraníme IČ 123456789000 ale stále nám projde 123. Chyba.
Jako většina idenfikačních čísel má i IČ svůj formát. Všimli jste si např, že se velmi špatně hledají dvě IČ, která by byla po sobě jdoucí? Nebo že se špatně hledají IČ, která by byla "pěkná", např. 12345678? Je to proto, že mezi číslicemi IČ je určitý matematický vstah. A to tento:
Prosté. A teď se přiznejte, kdo to pochopil :) S touto znalostí můžeme upravit naší kontrolní funkci, aby skutečně ověřovala správnost formátu IČ:
function validIc($ic) {
if (!ctype_digit($ic) || $ic > 99999999) return false;
// Pro vypocet nutno doplnit IC uvodnimi nulami
$ic = sprintf("%08s", $ic);
$a = 0;
for ($i = 0; $i < 7; $i++) $a += $ic[$i] * (8 - $i);
$a = $a % 11;
$c = 11 - $a;
if ($a == 1) $c = 0;
if ($a == 0) $c = 1;
if ($a == 10) $c = 1;
if ($ic[7] != $c) return false; // validaci neproslo
return true; // validaci proslo
}
Touto jednoduchou funkcí můžeme ověřit, zda zadané IČ může být platné, nikoliv zda platné je. Pokud chcete mít skutečně jistotu, že zadané IČ má nejen správný formát ale i v ČR existuje, je nutné nahlédnout do nějaké databáze IČ, například do systému ARES provozovaného ministerstvem financí. O něm se patrně zmíním později.
Dec 8, 2010 9:35:16 PM A v cem se ten muj algoritmus lisi od toho popsaneho Davidem? Jedna se o zcela totoznou vec, akorat misto regularu na zacatku mam ctype_digit...
Dec 8, 2010 9:35:16 PM Jen pro info: Je treba pocitat s firmami, ktere IC jeste nemaji, takze je dobre mit checkbox "Firma ceka na IC / Firma jeste nema prideleno IC", ktery umozni projit temto firmam pres validaci IC.
Dec 8, 2010 9:35:16 PM Moderněji a lépe: http://latrine.dgx.cz/jak-overit-platne-ic-a-rodne-cislo
Jan 2, 2011 11:13:35 PM Se schválně vyhýbáte regulárním výrazům? THX za info o IČu(max. 8 míst) $RegExp = "/^[0-9]{4,8}$/"; a pak by se s tím dalo dělat hodně věcí nebo jenom "/^[0-9]{8}$/"
May 11, 2011 9:42:52 PM vasio: timhle regularem projde i 12345678, ale to neni platne IC a ani byt nemuze - viz. ty matematicky zakonitosti na pozadi.