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

před použitím zatřepat myší!

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ářů.

Karma body: 69. Líbil se vám článek?

Komentáře » přidat

  1. avatar [1] BlackSUN: 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
  2. avatar [2] Pobert: 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
  3. avatar [3] peCan: 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. [4] Adam Šnobl: 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
  5. avatar [5] Pavel Jaroš: 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
  6. avatar [6] marek: 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. [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. [8] Shaman: 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
  9. avatar [9] Morty: 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. [10] Piki: 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
    Na komentář reagoval [13] LLook
    Na komentář reagoval [22] Jan Tichý
  11. [11] Jakub Hejda: 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
  12. avatar [12] zirafka: 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
  13. avatar [13] LLook: 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. [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
    Na komentář reagoval [41] Ondra
  15. [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
  16. avatar [16] tracy: 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
    Na komentář reagoval [35] rony
  17. avatar [17] marty: 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. [18] hvge: 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. [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. [20] pixy: 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. [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
  22. avatar [22] Jan Tichý: 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. [23] venca: nový

    hmm…velmi zajmavé

    Posláno 14. 9. 2007 v 16.05 | Odpovědět
  24. avatar [24] LLook: 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
  25. avatar [25] David Grudl: 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
    Na komentář reagoval [42] HoP
  26. [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. [27] Arthur Dent: 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. [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
    Na komentář reagoval [33] Věroš
    Na komentář reagoval [36] zajDee
  29. [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
    Na komentář reagoval [34] Věroš
  30. [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
  31. avatar [31] Black Wolf: 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
  32. avatar [32] David Grudl: 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
  33. avatar [33] Věroš: 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
  34. avatar [34] Věroš: 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
  35. avatar [35] rony: nový

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

    Posláno 17. 9. 2007 v 17.51 | Odpovědět
  36. avatar [36] zajDee: 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š
  37. avatar [37] Martin Bumba: 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
  38. avatar [38] David Grudl: nový

    [37] Martin Bumba:

    or fuck off
    Posláno 18. 9. 2007 ve 21.29 | Odpovědět
  39. [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
  40. avatar [40] Věroš: 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. [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. [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. [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
  44. avatar [44] Vlasta: 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
  45. avatar [45] David Grudl: 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
  46. avatar [46] David Grudl: 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
  47. avatar [47] Marian Cerny: 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
  48. avatar [48] Peca: 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á.

La Trine © 2004, 2008 David Grudl – o webu
provozuje Pachollini.

Jakékoliv užití obsahu, včetně převzetí článků nebo jejich částí, je bez předchozího písemného svolení autora zakázáno.

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