Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Translate to English… Ins Deutsche übersetzen…

Jak ověřit platné IČ a rodné číslo?

Víte, že rodné číslo nemusí být dělitelné 11? Že algoritmus ministerstva vnitra pro ověřování IČ je špatný? A že jej používá celá řada aplikací? A co na to Jan Tleskač?

Je užitečné, pokud aplikace (nejen webové) umí ověřit platnost různých identifikátorů, jako je třeba e-mail, rodné číslo, IČ a podobně. Naopak průseroidní je, když ověřovací algoritmus obsahuje chybu a digitální nepřítel pak tvrdošíjně odmítá vaše nacionále. Ukecat se nenechá, třísknout ho nemůžete.

Zrovna ohledně ověřování rodných čísel a IČ se obávám, že chybných bude většina implementací. Problém je v nedostatečném zdokumentování algoritmů, takže programátoři často spoléhají na neověřené informace. Jako skutečně kvalitní studnici vědění bych doporučil:

Hned si jej stáhněte!

Ověření rodného čísla

Začnu parafrází z pédéefka:

Do roku 1985 bylo přiděleno cca 1000 rodných čísel, která nejsou dělitelná 11. Není vyloučeno, že se v minimálním počtu vyskytly i po tomto roce.

Ale pozor, není to tím, že by úředníci na matrice byli trulanti! Dělitelnost jedenácti totiž bůh nikdy nesliboval. Algoritmus je ve skutečnosti následující:

  1. spočti zbytek po dělení prvních devíti číslic a čísla 11
  2. je-li zbytek 10, musí být poslední číslice 0
  3. jinak poslední číslice musí být rovna zbytku

Tedy 780123/3540 je korektní rodné číslo, ačkoliv není dělitelné jedenácti. No, nechtěl bych je mít, dovedu si představit ten všudypřítomný opruz :-)

Implementace v PHP:

function verifyRC($rc)
{
    // "be liberal in what you receive"
    if (!preg_match('#^\s*(\d\d)(\d\d)(\d\d)[ /]*(\d\d\d)(\d?)\s*$#', $rc, $matches)) {
        return FALSE;
    }

    list(, $year, $month, $day, $ext, $c) = $matches;

    // do roku 1954 přidělovaná devítimístná RČ nelze ověřit
    if ($c === '') {
        return $year < 54;
    }

    // kontrolní číslice
    $mod = ($year . $month . $day . $ext) % 11;
    if ($mod === 10) $mod = 0;
    if ($mod !== (int) $c) {
        return FALSE;
    }

    // kontrola data
    $year += $year < 54 ? 2000 : 1900;

    // k měsíci může být připočteno 20, 50 nebo 70
    if ($month > 70 && $year > 2003) $month -= 70;
    elseif ($month > 50) $month -= 50;
    elseif ($month > 20 && $year > 2003) $month -= 20;

    if (!checkdate($month, $day, $year)) {
        return FALSE;
    }

    // cislo je OK
    return TRUE;
}

Funkce se řídí heslem „buďte přísní v tom, co posíláte, a buďte velkorysí v tom, co přijímáte.“ Uživatel tak může zadat RČ i s lomítkem nebo mezerami.

Ještě poznámka – stejný systém rodných čísel používají i na Slovensku, takže kód mohou použít i bratia programátori.

Ověření IČ

Před lety jsem napsal webovou aplikaci pro jistou firmu, kde jsem použil ověřování platnosti IČO (tehdy ještě IČO, dnes už IČ). Vycházel jsem z algoritmu publikovaného na stránkách ministerstva vnitra. Jaké bylo překvapení, když si klient zkušebně zadal své vlastní IČO a aplikace mu oznámila, že je neplatné.

Dodnes toto IČO (25596641) používám k otestování aplikací, jestli také nepoužívají vadný algoritmus. A řeknu vám, většina neprojde.

Takže, jak se ověřuje IČ? Například 69663963

  1. první až sedmou číslici vynásobíme čísly 8, 7, 6, 5, 4, 3, 2 a součiny sečteme:

    soucet = 6*8 + 9*7 + 6*6 + 6*5 + 3*4 + 9*3 + 6*2 = 228

  2. spočítáme zbytek po dělení jedenácti: zbytek = soucet % 11
  3. pro poslední osmou číslici c musí platit:
    • je-li zbytek 0 nebo 10, pak c = 1
    • je-li zbytek 1, pak c = 0
    • v ostatních případech je c = 11 - zbytek

Implementace v PHP:

function verifyIC($ic)
{
    // "be liberal in what you receive"
    $ic = preg_replace('#\s+#', '', $ic);

    // má požadovaný tvar?
    if (!preg_match('#^\d{8}$#', $ic)) {
        return FALSE;
    }

    // kontrolní součet
    $a = 0;
    for ($i = 0; $i < 7; $i++) {
        $a += $ic[$i] * (8 - $i);
    }

    $a = $a % 11;

    if ($a === 0) $c = 1;
    elseif ($a === 10) $c = 1;
    elseif ($a === 1) $c = 0;
    else $c = 11 - $a;

    return (int) $ic[7] === $c;
}

Přepis do JavaScriptu už nechám na vás. Můžete ho pastnout do komentářů.

Komentáře RSS 2.0 komentářů » přidat

avatar

#1 BlackSUN http://krabice.info nový

Díky za osvětu i za poskytnutí uvedených kódů, myslím, že se budou nejednomu programátorovi ho­dit.

Posláno 14. 9. 2007 v 5.42 | Odpovědět
avatar

#2 Pobert pobert@seznam.cz nový

Podobné to je i u bankovních účtů.
informace o algoritmu jsou na stránkách ČNB – příloha vyhlášky 62/2004:
V tuzemském platebním styku musí být první část čísla účtu a základní část čísla účtu
samostatně zajištěny pomocí modulo 11 s váhami uvedenými v následující tabulce:
Algoritmus kontroly čísla ABCDEFGHIJ na modulo 11
Číslice A B C D E F G H I J
Váhy 6 3 7 9 10 5 8 4 2 1
n 10 9 8 7 6 5 4 3 2 1
kde n je pozice číslice v čísle účtu (počítáno zprava)
Váhy jsou získány jako rozdíl n-té mocniny 2 a nejbližšího nižšího násobku 11.
Váhy se k číslicím na jednotlivých pozicích čísla účtu přiřazují zprava. Číslo ABCDEFGHIJ je zajištěno pomocí
modulo 11, pokud je součet S beze zbytku dělitelný 11, přičemž
S = J 1 + I 2 + H 4 + G 8 + F5 + E10 + D9 + C7 + B*3 + A *6

A IBAN má také kotrolní číslice (první 2 čísla za kódem země)

Posláno 14. 9. 2007 v 8.27 | Odpovědět
avatar

#3 peCan http://pecan.cz nový

Taky jsem kdysi řešil kontrolu RČ a datum narození z něho. Když se na to teď tak dívám, taky to šlo řešit jednodušeji;-)

Posláno 14. 9. 2007 v 8.50 | Odpovědět

#4 Adam Šnobl http://snobl.wz.cz nový

Velmi dobře! Kontrolu IČ jsem (v Javě) implementoval dobře, ale o té specialitě u rodného čísla jsem nevěděl. To budu muset přepsat. Díky za upozornění!

Posláno 14. 9. 2007 v 9.36 | Odpovědět
avatar

#5 Pavel Jaroš http://jaros.ezin.cz/ nový

I já mám rád Zeleného Raoula, ale na internetu by otázka správně měla znít: Co na to RH? ;-)

Posláno 14. 9. 2007 v 9.37 | Odpovědět
avatar

#6 marek http://www.mixa.name nový

osobně se setkávám ještě s jednou vadou na kráse… má web s koncovkou .name , často narazímu zadávání emailu :(

Posláno 14. 9. 2007 v 9.53 | Odpovědět

#7 mANY nový

Zcela mimo téma: „Vycházel jsem z algoritmu publikovaného na stránkách ministerstva vnitra.“

Posláno 14. 9. 2007 v 10.20 | Odpovědět

#8 Shaman http://www.adaptic.cz nový

Díky za užitečný článek. Skutečně se mi teď hodí.

Posláno 14. 9. 2007 v 10.49 | Odpovědět
avatar

#9 Morty http://www.koldasoft.cz nový

Jen tak pro zajímavost jsem si vyhledal co je to IČ zač.. zajímavé :-)
Jinak rozhodně přínosný článek.

Posláno 14. 9. 2007 v 11.10 | Odpovědět

#10 Piki http://www.piki.zh4a.sk nový

Koho tieto algoritmy na tvorbu čísiel a hlavne prečo napadajú?

Posláno 14. 9. 2007 v 11.53 | Odpovědět
Na komentář reagoval [12] zirafka [13] LLook [22] Jan Tichý

#11 Jakub Hejda http://www.clickmedia.cz nový

Tééééda. to, že rodné číslo nemusí být dělitelné 11 beze zbytku jsem věděl. Ale ty ostatní informace jsou pro mne naprosto nové. Děkuji !

Posláno 14. 9. 2007 ve 12.04 | Odpovědět
avatar

#12 zirafka http://blog.zirafka.cz nový

#10 Piki: Jedna se o tzv. samoopravne kody. Uz nejakou dobu se o nich chystam napsat clanek. Takhle bych se do toho uz konecne mohla pustit (-:

Posláno 14. 9. 2007 ve 12.25 | Odpovědět
Na komentář reagoval [18] hvge
avatar

#13 LLook http://llook.wz.cz/weblog/ nový

Vždycky jsem si lámal hlavu nad tím, jak byl asi u rodných čísel vyřešen problém Y2K. Teď už to vidím, ve skutečnosti jsou rodná čísla náchylná akorát k problému Y2K54…

#10 Piki: Kontrolní mechanizmy jsou potřeba. Třeba u čísla účtu – představ si situaci, že posíláš peníze na zahraniční účet (drahá operace, která trvá strášně dlouho) a překlepneš se. Nebo příkaz podáváš přímo v bance a překlepne se úřednice… Možností je spousta.

Posláno 14. 9. 2007 ve 12.32 | Odpovědět

#14 Mormegil nový

No, když už se tady šťourá do těch velice okrajových případů, tak to chce dělat to důsledně (a to nemluvím o tom ? 200 : 1900 v kódu ;-) ). Přečtěte si třeba článek na Wikipedii a dozvíte se, že platnými rodnými čísly jsou také např. 0531135099 či 0681186066.

A taky by vás mohlo zajímat, že na to, jak vypadá RČ, má zákon poněkud jiný názor než ISVS – viz § 13, odstavec 3 zákona 302/2004 Sb. A teď babo raď, že?

Posláno 14. 9. 2007 ve 12.38 | Odpovědět
Na komentář reagoval [25] David Grudl [41] Ondra

#15 David V. nový

Díky moc za článek.
Jak jsem zjistil, tak také v naší aplikaci máme chybu … Grrr :-(

Posláno 14. 9. 2007 ve 12.56 | Odpovědět
avatar

#16 tracy thomas.tracy@email.cz nový

Vtipné je, že podle toho dokumentu je validní i e-mailová adresa a@b (tedy 3 znaky)…

Posláno 14. 9. 2007 ve 13.21 | Odpovědět
Na komentář reagoval [24] LLook [35] rony
avatar

#17 marty marty@hranice.cz nový

marty…
proc script pro RC?
ja to taky programoval loni… :-)
potreboval jsem to do knihy paleni, kde se eviduji RC pro potrebu celniku. A musel jsem nejak kontrolovat zda obsluha zadala spravne RC.. :-)

Posláno 14. 9. 2007 ve 13.23 | Odpovědět

#18 hvge http://hvge.sk nový

#12 zirafka: V tomto pripade sa kod skor len kontroluje. Dufam ze tam ale potom spomenieš aj moj oblubeny Golayov kod (perfect binary Golay code), s ktoreho tabulkami a rucnym pocitanim som sa onehda trapil na skuske z teorie kodovania :)

..inak pekny clanok, dufam ze to RČ plati aj u nas na SVK:)

Posláno 14. 9. 2007 ve 14.15 | Odpovědět

#19 HoP nový

A víte, že IČ nemusí mít 8 číslic ale i méně?

Posláno 14. 9. 2007 ve 14.31 | Odpovědět
Na komentář reagoval [25] David Grudl

#20 pixy http://pixy.cz nový

Tak jako jo, Davide, trulant dobrej. Ale co furunkl? Ha?!

Posláno 14. 9. 2007 v 15.34 | Odpovědět
Na komentář reagoval [25] David Grudl

#21 DFly nový

no, spravuji system ktery eviduje urctou (dost velkou) skupinu obyvatel CR, a take jsem se musel vyporadat s RC…
To ze modulo 11 funguje az od 10ti mistnych rodnych cisel je jeden z problemu (nekde to mam presne, ale je to od roku cca 1950), nicmene i v techto novych RC jsou nekdy nesystemove problemy, napr RC (ktere jsem i osobne overoval z rodneho listu) ktere neprojde kontrolou %11, nebo shodna RC (vznikalo to v dobe kdy porodnice meli malo cisel a volali do jine v okrese, aby jim dali nejaka prebyvajici, ale nakonec i tato se pouzila a pod. pripady)
Takze nakonec system musi mit nejaky jiny unikatni kod, a po osobnim overeni musi mit flag, kterej deaktivuje hlaseni automaticke kontroly.

Posláno 14. 9. 2007 v 15.35 | Odpovědět
Na komentář reagoval [25] David Grudl
avatar

#22 Jan Tichý http://www.jantichy.cz nový

#10 Piki: Jsou to algoritmy, které zabezpečují číslo proti nejčastějším chybám, ke kterým dochází. V tomto případě tedy proti překlepu v jedné číslici a proti prohození dvou sousedních číslic.

Posláno 14. 9. 2007 v 15.55 | Odpovědět

#23 venca http://www.freeblog.ic.cz nový

hmm…velmi zajmavé

Posláno 14. 9. 2007 v 16.05 | Odpovědět
avatar

#24 LLook http://llook.wz.cz/weblog/ nový

#16 tracy: A ona snad není validní? Co když zítra ICANN nějaké instituci přidělí doménu B? Je fakt, že podle toho dokumentu by nějaké nevalidní adresy prošly (třeba .@.), ale zrovna a@b je OK.

Posláno 14. 9. 2007 v 16.22 | Odpovědět
avatar

#25 David Grudl http://davidgrudl.com nový

#14 Mormegil: to je velmi dobrá připomínka, ale šlo by to sdělit méně kokotsky. Kód jsem upravil.

#19 HoP: nevíme. Máš nějaký příklad? Nebo nejde jen o opomenutí levostranných nul?

#20 pixy: furunkl se udělal našemu pejskovi na nose, takže u mě splněno na 100 %. Co ty a Arthur? ;-)

#21 DFly: řadu věcí by ti mohl osvětlit tento článek

Posláno 14. 9. 2007 ve 20.06 | Odpovědět
Na komentář reagoval [26] DFly [42] HoP

#26 DFly nový

#25 David Grudl: ten system jsem delal nekdy pred osmi lety, a shanel jsem spoustu informaci pres kamene ustavy nasich uradu – na webu toho moc nebylo
k rodnym cislum: v tom systemu jsou dve RC na ktere nefunguje %11 a nekonci nulou (nejspis se nekdo uklepl na stroji, nebo podobny omyl – ale je to v rodnem liste, tak to musim brat jako OK)
a shody RC mam overene 4
dokonce by se dle RC mela dat poznat i porodnice, nebo alespon kraj(okres) pro ktere byli urcita cisla prirazena, jenze ono diky tomu predavani prebytecnych cisel tam kde jich byl nedostatek se dal urcit jen kraj – zkusim jeste prohledat svoje archivy, nekde budu mit podklady, podle kterych jsem to delal
nevim jak je to ted s rozdavanim cisel, jestli se berou z nejakeho predgenerovaneho zasobniku, nebo jestli jeste plati to rozhazovani cisel na porodnice
ten system bezi stale, a obcas ho dohleduju

Posláno 14. 9. 2007 ve 23.01 | Odpovědět

#27 Arthur Dent http://www.misantrop.info nový

Myslím, že bys měl především napsat Ruby verzi, té by se dostalo v komunitě jistě velmi vřelého přivítání.

PS: Prohlížel jsem psa, furunkl žádnej, trulanty dva.

Posláno 14. 9. 2007 ve 23.36 | Odpovědět

#28 DFly nový

Takze ted jsem na neco koukal, a prvni dve cisla za lomitkem by meli znacit cislo porodnice a treti poradi (zvlast kluci i holky diky +50), ale kolik je na tom pravdy nevim – mozna to platilo drive…
a Praha se taky bude mozna odlisovat, v rodine jsem si neco overoval a ne vsechno sedi (mozna ted se uz porodnice maji jina cisla nez pred 30 lety)
a jestli je v republice do 98 porodnic netusim (typnul bych ze vice)
99 za lomitkem znaci cizince ktery nema klasicke cislo z matriky

Posláno 15. 9. 2007 v 0.11 | Odpovědět
Na komentář reagoval [29] karel [33] Věroš [36] zajDee

#29 karel nový

#28 DFly: Já a můj brácha jsme se narodili ve stejné porodnici a první dvě čísla za lomítkem máme úplně jiná.

Jinak na základě tvého pravopisu, používání interpunkce a diakritiky se mi moc nechce věřit, že jsi před osmi lety dělal nějaký systém pro rodná čísla, tipoval bych Tě na pubertální věk.

Posláno 15. 9. 2007 v 16.38 | Odpovědět
Na komentář reagoval [30] DFly [34] Věroš

#30 DFly nový

#29 karel: hmm, kdyz si to myslis, ja ti to vymlouvat nebudu…

Posláno 15. 9. 2007 ve 22.04 | Odpovědět
avatar

#31 Black Wolf http://www.kandr.name nový

Pěkný a užitečný článek, obzvláště to IČ se mi teď docela hodilo a pomohlo mi.

Ovšem v tom RČ si myslím že je malá chybička – projde tím rč které je teoreticky správné, ale datum narození je v budoucnosti. Myslím že by to projít nemělo, když se jeho potenciální nositel ještě nenarodil;)

Posláno 16. 9. 2007 v 19.39 | Odpovědět
Na komentář reagoval [32] David Grudl
avatar

#32 David Grudl http://davidgrudl.com nový

#31 Black Wolf: jasně, projde tím i RČ, které má datum narození v minulosti, ale stejně nebylo nikomu přiděleno. Algoritmus ověřuje pouze formální platnost a můžeš si ho sám jakkoliv vylepšít.

Posláno 16. 9. 2007 ve 20.29 | Odpovědět
avatar

#33 Věroš http://www.na-mytince.cz/ nový

#28 DFly: „Oh no a special case!“

Já nejsem cizinec a poslední dvojčíslí mi končí na 99. :-)

Posláno 17. 9. 2007 v 9.08 | Odpovědět
Na komentář reagoval [36] zajDee
avatar

#34 Věroš http://www.na-mytince.cz/ nový

#29 karel: Čísla za lomítkem můžou být způsobená tím že jste se narodili před 1993 a po 1993, kdy se měnily čísla u porodnic nebo spoustou jiných důvodů (bordel na matrice, moc dětí narozených v jeden den, apod.)

Posláno 17. 9. 2007 v 9.34 | Odpovědět
avatar

#35 rony http://spravodaj.madaj.net/ nový

#16 tracy: jojo, na mojom serveri „b“ mam mailbox „a“ :-)

Posláno 17. 9. 2007 v 17.51 | Odpovědět
avatar

#36 zajDee zajdee@centrum.cz nový

#33 Věroš: Ale #28 DFly: psal o prvním dvojčíslí za lomítkem, ne?:-)

Mé rodné číslo naštěstí projde ověřením na modulo 11, ale dokážu si představit problém, kdy někdo dostane číslo, které je úplně mimo ověření modulo 11 i modulo 10.

A to nemluvím o číslech ze starších let, než 1953…

(Pamatuju si, že babička musela někdy před deseti lety dohledávat své správné rodné číslo přes několik matrik, měla v té době dvě – naštěstí potkala pracovité úředníky, takže se povedlo a dnes už má své správné rodné číslo s trojčíslím za lomítkem:-))

Posláno 18. 9. 2007 v 11.27 | Odpovědět
Na komentář reagoval [40] Věroš
avatar

#37 Martin Bumba http://evil666.net nový

Zdravím prosím už to někdo přepsal do JS potřeboval bych to v JS a moc se me to nechce prepisovat díky :).

Posláno 18. 9. 2007 ve 20.14 | Odpovědět
Na komentář reagoval [38] David Grudl
avatar

#38 David Grudl http://davidgrudl.com nový

#37 Martin Bumba:

or fuck off
Posláno 18. 9. 2007 ve 21.29 | Odpovědět

#39 FiJi nový

Ale pozor, není to tím, že by úředníci na matrice byli trulanti!
Dělitelnost jedenácti totiž bůh nikdy nesliboval. Algoritmus je
ve skutečnosti následující:
spočti zbytek po dělení prvních devíti číslic a čísla 11
je-li zbytek 10, musí být poslední číslice 0
jinak poslední číslice musí být rovna zbytku

Současný zákon dělitelnost 11 ale slibuje a i podle popisu na wikipedii to vypadá, že chyba je opravdu spíš v tom algoritmu.

Možná by taky stálo za to doplnit do článku, kde se tam vzalo těch 20 a 70, to myslím taky není obecně známo…

Posláno 19. 9. 2007 v 9.11 | Odpovědět
avatar

#40 Věroš http://www.na-mytince.cz/ nový

#36 zajDee: Omlouvám se za překlep. – Samozřejmě poslední čtyřčíslí mi začíná 99.

Posláno 19. 9. 2007 v 11.29 | Odpovědět

#41 Ondra nový

#14 Mormegil: Moje prababička se narodila v roce 1898 a teď ji nechtěl přijmout praktický lékař, protože novorozence pojišťovna hradí jen lékařům dětským.

Posláno 20. 9. 2007 v 15.22 | Odpovědět

#42 HoP nový

#25 David Grudl: Příklad nemám, někdo mi o tom vyprávěl, bohužel sem tomu nevěnoval moc pozornost, protože to nebyla věc, která by mne nějak znepokojovala. Zkusím to zjistit.

Posláno 1. 10. 2007 ve 13.17 | Odpovědět
Na komentář reagoval [43] HoP

#43 HoP nový

#42 HoP: Tak jsem zkusil najít ten příklad a zjistil jsem, že měli v databázi pouze špatně zadané IČ, tzn. že jim vypadla jedna číslice… Takže se omlouvám za mystifikaci, IČ má skutečně 8 číslic, případě je doplněno nulami.

Posláno 2. 10. 2007 ve 13.14 | Odpovědět
avatar

#44 Vlasta aspcreator@yahoo.com nový

Validace RC je zajimavy problem. Jen tak pro zajimavost, co se z RC da vycist.

mesic + 50 = zana
den + 50 = cizinec, zijici v CR

Pro zadavani a validaci RC jsem udelal Reg vyraz, ktery zohlednuje i prestupny rok. Tak to vyzkousejte a dejte vedet, jak se vam to chova.

regex = new Regex(@„^(((^\­d?$)|(^\d{2}$)|(^\d{2}(0­|1|5|6)$)|(^\d{2}(0|5)[1–9]$)|(^\d{2}(1|6)[0–2]$)|(^\d{2}(­01|51)[01235678]$)|(^\d{­2}(02|52)[012567]$)|(^\d­{2}(03|53)[01235678]$)|(­^\d{2}(04|54)[01235678]$­)|(^\d{2}(05|55)[0123567­8]$)|(^\d{2}(06|56)[0123­5678]$)|(^\d{2}(07|57)[0­1235678]$)|(^\d{2}(08|58­)[01235678]$)|(^\d{2}(09­|59)[01235678]$)|(^\d{2}­(10|60)[01235678]$)|(^\d­{2}(11|61)[01235678]$)|(­^\d{2}(12|62)[01235678]$­)|(^\d{2}(010|020|030|04­0|050|060|070|080|090|10­0|110|120)[1–9]$)|(^\d{2}(­015|025|035|045|055|065|­075|085|095|105|115|125)­[1–9]$)|(^\d{2}(­510|520|530|540|550|560|­570|580|590|600|610|620)­[1–9]$)|(^\d{2}(­515|525|535|545|555|565|­575|585|595|605|615|625)­[1–9]$)|(^\d{2}(­011|021|031|041|051|061|­071|081|091|101|111|121)­[0–9]$)|(^\d{2}(­016|026|036|046|056|066|­076|086|096|106|116|126)­[0–9]$)|(^\d{2}(­511|521|531|541|551|561|­571|581|591|601|611|621)­[0–9]$)|(^\d{2}(­516|526|536|546|556|566|­576|586|596|606|616|626)­[0–9]$)|(^\d{2}(­012|032|042|052|062|072|­082|092|102|112|122)[0–9]$)|(^\d{2}(­017|037|047|057|067|077|­087|097|107|117|127)[0–9]$)|(^\d{2}(­512|532|542|552|562|572|­582|592|602|612|622)[0–9]$)|(^\d{2}(­517|537|547|557|567|577|­587|597|607|617|627)[0–9]$)|(^\d{2}(­013|033|053|073|083|103|­123)[01]$)|(^\d{2}(018|0­38|058|078|088|108|128)[­01]$)|(^\d{2}(513|533|55­3|573|583|603|623)[01]$)­|(^\d{2}(518|538|558|578­|588|608|628)[01]$)|(^\d­{2}(043|063|093|113)[0]$­)|(^\d{2}(048|068|098|11­8)[0]$)|(^\d{2}(543|563|­593|613)[0]$)|(^\d{2}(54­8|568|598|618)[0]$)|(^\d­{2}(022|027|522|527)[0–8]$)|(^(00022­|00027|00522|00527|04022­|04027|04522|04527|08022­|08027|08522|08527)[0–9]$)|(^(12022­|12027|12522|12527|16022­|16027|16522|16527)[0–9]$)|(^(20022­|20027|20522|20527|24022­|24027|24522|24527|28022­|28027|28522|28527)[0–9]$)|(^(32022­|32027|32522|32527|36022­|36027|36522|36527)[0–9]$)|(^(40022­|40027|40522|40527|44022­|44027|44522|44527|48022­|48027|48522|48527)[0–9]$)|(^(52022­|52027|52522|52527|56022­|56027|56522|56527)[0–9]$)|(^(60022­|60027|60522|60527|64022­|64027|64522|64527|68022­|68027|68522|68527)[0–9]$)|(^(72022­|72027|72522|72527|76022­|76027|76522|76527)[0–9]$)|(^(80022­|80027|80522|80527|84022­|84027|84522|84527|88022­|88027|88522|88527)[0–9]$)|(^(92022­|92027|92522|92527|96022­|96027|96522|96527)[0–9]$))|(^\d{6}[0–9]{1,4}))$“);

Posláno 3. 10. 2007 v 9.55 | Odpovědět
avatar

#45 David Grudl http://davidgrudl.com nový

Přepis do JavaScriptu mi poslal Filip Oščádal

function testICO(x)
{
  try
  {
    var a = 0;
    if(x.length == 0) return true;
    if(x.length != 8) throw 1;
    var b = x.split('');
    var c = 0;
    for(var i = 0; i < 7; i++) a += (parseInt(b[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(parseInt(b[ 7]) != c) throw(1);
  }
  catch(e)
  {
    alert('Zadaný údaj není korektní!');
    return false;
  }
  return true;
}
function testRC(x, age)
{
  if(!age) age = 0;
  try
  {
    if(x.length == 0) return true;
    if(x.length < 9) throw 1;
    var year = parseInt(x.substr(0, 2), 10);
    var month = parseInt(x.substr(2, 2), 10);
    var day = parseInt( x.substr(4, 2), 10);
    var ext = parseInt(x.substr(6, 3), 10);
    if((x.length == 9) && (year < 54)) return true;
    var c = 0;
    if(x.length == 10) c = parseInt(x.substr(9, 1));
    var m = parseInt( x.substr(0, 9)) % 11;
    if(m == 10) m = 0;
    if(m != c) throw 1;
    year += (year < 54) ? 2000 : 1900;
    if((month > 70) && (year > 2003)) month -= 70;
    else if (month > 50) month -= 50;
    else if ((month > 20) && (year > 2003)) month -= 20;
    var d = new Date();
    if((year + age) > d.getFullYear()) throw 1;
    if(month == 0) throw 1;
    if(month > 12) throw 1;
    if(day == 0) throw 1;
    if(day > 31) throw 1;
  }
  catch(e)
  {
    alert('Zadaný údaj není korektní!');
    return false;
  }
  return true;
}
function testDIC(x)
{
  try
  {
    if(x.length == 0) return true;
    var id = x.substr(0, 2).toUpperCase();
    x = x.substr(2);
    if((id == 'CZ') || (id == 'SK'))
    {
      if(x.length < 8) throw 1;
      if(x.length > 11) throw 1;
      if(x.length == 8)
      {
        return testICO(x);
      }
      else
      {
        return testRC(x, 18);
      }
      throw 1;
    }
    alert('Není možné zkontrolovat DIČ mimo Českou a Slovenskou republiku!');
    return true;
  }
  catch(e)
  {
    alert('Zadaný údaj není korektní!');
    return false;
  }
}

…to be continued

Posláno 9. 10. 2007 ve 14.26 | Odpovědět
avatar

#46 David Grudl http://davidgrudl.com nový

(pokračování řešení od Filipa Oščádala)

  • jako správnou hodnotu skript bere i prázdnou hodnotu (viz. modře označené řádky), test na prázdnou hodnotu by mělo dělat PHP
  • test rodného čísla lze podmínit i na věk osoby (testuje se jen rok, pro přesnost by bylo nutné porovnávat čas v sekundách)
  • test na validitu data je jen přibližný (netestuje se přestupný rok a 30./31. den v měsíci)

příklad použití:

<input onblur="if(!testRC(this.value)) this.focus();"
  name="rc" size="10" value="" maxlength="10" type="text">

<input onblur="if(!testICO(this.value)) this.focus();"
  name="ico" size="8" value="" maxlength="8" type="text">

<input onblur="if(!testDIC(this.value)) this.focus();"
  onclick="if(this.value.length < 2) this.value = 'CZ';"
  name="dic" size="13" value="" maxlength="13" type="text">

(test DIČ využívá testů IČO a RČ)

Posláno 9. 10. 2007 ve 14.28 | Odpovědět
avatar

#47 Marian Cerny http://jojo.matfyz.cz/ nový

Pri overovani RC to nie je uplne dotiahnute. Ak je RC 9 miestne a rok < 54, mala by este nasledovat kontrola datumu pomocou checkdate().

Posláno 10. 10. 2007 v 6.03 | Odpovědět
avatar

#48 Peca petr.dana@gmail.com nový

Nevím, jestli si to tu někdo ještě přečte, ale kdyby náhodou… Asi ten algoritmus pořád není správně, nebo existují firmy s IČ, která nejsou správně vygenerovaná. Např. tohle: 72343976 (http://wwwinfo.mfcr.cz/…es_subjx.cgi?…)

Posláno 16. 11. 2007 ve 12.14 | Odpovědět

Tento článek byl uzavřen. Už není možné k němu přidávat komentáře ani hlasovat

Výtah na začátek článku na první komentář

Názory čtenářů v diskusích nejsou názory provozovatele webu, a ten za jejich obsah neodpovídá.

phpFashion © 2004, 2010 David Grudlo webu

Pokud není uvedeno jinak, podléhá obsah těchto stránek licenci Creative Commons BY-NC-ND Creative Commons License BY-NC-ND

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.