…meie igapäevast IT’d anna meile igapäev…

2010-04-05

Eesti isikukoodi valideerimine JavaScriptis

Filed under: Eesti,JavaScript — Sander @ 12:02:26
Tags: , ,

Allpool olev funktsioon valideerib Eesti isikukoodi JavaScriptis. Leitakse ka sugu (isMale) ja sünnikuupäev (bd). Juhul, kui neid vaja ei ole, siis kommenteeri vastavad read välja.

Kunagi sai ka kirjutatud isikukoodi valideerimisest .NET’is, loe siit.

  1. function validateIdCode(idCode) {
  2.     if (idCode.length != 11) {
  3.         return false;
  4.     }
  5.     if (isNaN(idCode)) {       
  6.         return false;
  7.     }
  8.    
  9.     //Sex, use if needed, otherwise comment out.
  10.     var isMale = ((idCode.substr(0, 1)) % 2 != 0);
  11.     var century = 0;
  12.     // check century
  13.     switch (idCode.substr(0, 1)) {
  14.         case ‘1’:
  15.         case ‘2’:
  16.             {
  17.                 century = 1800;
  18.                 break;
  19.             }
  20.         case ‘3’:
  21.         case ‘4’:
  22.             {
  23.                 century = 1900;
  24.                 break;
  25.             }
  26.         case ‘5’:
  27.         case ‘6’:
  28.             {
  29.                 century = 2000;
  30.                 break;
  31.             }
  32.         default:
  33.             {               
  34.                 return false;
  35.             }
  36.     }
  37.     // check if birthday is a valid date       
  38.     var year = (century + new Number(idCode.substr(1, 2)));
  39.     var month = idCode.substr(3, 2);
  40.     var day = idCode.substr(5, 2);
  41.     //get birthdate. Comment out if not needed
  42.     var bd = new Date(year, month – 1, day);
  43.     if ((bd.getMonth() + 1 != month) || (bd.getDate() != day) || (bd.getFullYear() != year)) {       
  44.         return false;
  45.     }   
  46.     //9
  47.     var sum = new Number(idCode.substr(9, 1));
  48.     //0-8
  49.     for (i = 0; i <= 8; i++) {
  50.         sum = sum + new Number(idCode.substr(i, 1)) * (i + 1);
  51.     }
  52.     var check = sum % 11;
  53.     // special case, recalculate the checksum
  54.     if (check == 10) {
  55.         sum = 0;
  56.         for (i = 0; i <= 6; i++) {
  57.             sum = sum + new Number(idCode.substr(i, 1)) * (i + 3);
  58.         }
  59.         for (i = 7; i <= 9; i++) {
  60.             sum = sum + new Number(idCode.substr(i, 1)) * (i – 6);
  61.         }
  62.         check = sum % 11;
  63.         check = check % 10;
  64.     }
  65.     if (check != new Number(idCode.substr(10, 1))) {       
  66.         return false;
  67.     }
  68.     return true;
  69.    
  70. }

10 kommentaari »

  1. Muidu tore, kuid tõsine pain on lugeda koodi, kus on muutujad bd vms. birthday on tegelikult piisavalt lühike muutuja nimi ning selletõttu ei muutu javascripti fail palju suuremaks, kuid samas loetavus paraneb.

    kommentaar kirjutas Mart — 2010-04-05 @ 12:17:15 | Vasta

  2. Seda kindlasti, olen muutujate nimetamisest varem kirjutanud. Siinne bd on tegelikult hiljem lisatud jupike, mida oli konkreetse projekti raames vaja – rookisin koodist projektiga seotud asjad välja, aga nagu näha, isMale ja bd ei kasutata antud näites kusagil.

    kommentaar kirjutas dukelupus — 2010-04-05 @ 12:20:36 | Vasta

  3. Midagi sarnast on varem avaldanud oma blogis ka Mika Tuupola, kuigi tema versioon ainult valideeris kontrollnumbrit, aga ei otsinud välja sünniaega ega sugu – http://www.appelsiini.net/2009/9/verify-estonian-isikukood-with-javascript

    Mis aga koodi puutub, siis teeks mõned märkused:

    Konstruktsioon new Number(str) on selles kontekstis suhteliselt pointless. Kuna tegu on ainult tüübiteisendusega stringist numbriks, piisab Number(str) või parseInt(str). Operaator new mitte ei teisenda väärtust, vaid loob sisendi alusel numbriobjekti, aga see teisendatakse liitmistehteks tagasi “lihtnumbriks”.

    str.substr(offset, 1) asemel on mõistlik kasutada str.charAt(offset)

    switch lauset on väga ilusti kasutatud, tavaliselt kiputakse selle fall through võimalus ära unustama. Küll aga on loogelised sulud üleliigsed – nende töö teeb ära break ning seega pole vaja lausete blokki eraldi märgistada

    if (isNaN(idCode)).. on siin suht pointless, kuna NaN.length == “undefined” ja seega eelmises lauses olnud idCode.length!=11 on NaN väärtuse korral niikuinii juba rakendunud.

    isMale ja bd on funktsiooni skoobis küll olemas, kuid kuskile välja nad ei paista. Võibolla oleks parem tagastada “true” asemel objekt kujul {isMale: isMale, bd: bd}var idcheck = validateIdCode(isikukood); if(idchack){alert(idcheck.isMale?”mees”:”naine”);} else { alert(“Isikukood ei klapi!”);}

    kommentaar kirjutas andris — 2010-04-05 @ 12:45:08 | Vasta

  4. parseInti kasutades peab teadma, et näiteks parseInt(’08’) = 0

    kommentaar kirjutas Suvaline — 2010-04-05 @ 12:55:43 | Vasta

  5. Õige jah, korrektne süntaks oleks parseInt(val, 10), siis ei peeta nulliga algavaid numbreid ekslikult oktaalseteks.

    kommentaar kirjutas andris — 2010-04-05 @ 13:04:08 | Vasta

  6. Andris: isNan on vägagi vajalik, kuna sissetulev kood võib sisaldada ka muid sümboleid peale numbrite. Juhul, kui isikukoodis on täht, siis on loomulikult see vale kood ja võib ilma pikemata ka seda öelda. Pikkuse kontroll ei ole absoluutselt kindel meetod numbrite tuvastamiseks ;)

    Nagu ma ka ütlesin, jupp on pärit projektist, kus isMale ja bd on kasutuses. Nendega seotud funktsionaalsuse rookisin ülalolevast koodist välja. Kes vajab, see kasutab ise. Kes ei vaja, võib üldse välja kommenteerida.

    Lookelised sulud switch blokis on mittevajalikud, kuid mulle meeldib neid kasutada. Koodi loetavuse seisukohalt on nad mugavad.

    Ja substr vs charAt – lähemal vaatamisel oleks ehk pandud tähele, et päris mitmes kohas võetakse rohkem kui üks char korraga.

    kommentaar kirjutas dukelupus — 2010-04-05 @ 13:18:17 | Vasta

  7. PS. leedus kasutatakse täpselt sama isikukoodi formaati nagu eestis. st sama valem töötab ka leedu isikukoodidega.

    Kui minna webi rakendusega eestist välja, siis ei saa eeldada, et isikukood on unikaalne tunnus isiku tuvastamiseks.

    Lisaks on eestis ametlikult välja antud üksikud vigaseid isikukoode, mis valideerimise valemit ei läbi. st kontrollnumber on vigane.

    Nii, et olgem valmis eranditeks.

    kommentaar kirjutas Margus — 2010-04-05 @ 14:42:00 | Vasta

  8. Vaatasin jah ennem kiiruga valesti, probleem ei ole mitte isNaN asukohas (mis on tõesti õigesti), vaid hoopis esimeses tingimuslauses if(idCode.length!=11). Juhul kui sisendiks on number (mitte numbrit sisaldav string) validateIdCode(12345678901), siis antud tingimuslause feilib, kuna numbril pole omadust “length”. idCode.length oleks sellisel juhul “undefined” ja ei oleks võrdne väärtusega 11.

    Seda et substr oli kasutatud mitmes kohas, nägin küll, kuid arvan endiselt et substr ei ole ainult ühe sümboli lugemisel õiges kontekstis ja selle asemel tuleks kasutada just selleks tegevuseks mõeldud charAt meetodit. Kuid see on rohkem põhimõtte kui tulemuse või töökindluse küsimus – väljund on ju mõlemal funktsioonil sama.

    kommentaar kirjutas andris — 2010-04-05 @ 14:42:25 | Vasta

  9. Vb natuke teemaväline, aga javascripti puhul pole ju mõtet asja kuulikindlaks treida – script käib kasutaja arvutis. Kuulikindel peab olema serveripoolne kontroll, et suvalise sisendi korral antaks korrektne väljund.

    kommentaar kirjutas Suvaline — 2010-04-05 @ 15:33:43 | Vasta

    • Tõsi, antud näites siiski tasub olla hoolikas ja põhjalik, et mõni seda aluseks võttes serveripoolset koodi tehes reha otsa ei astuks. Serveripoolne kood tuleks teha standardile tuginedes ning mitte ühtegi näidet otseselt aluseks võttes, arvestades vaid kõikide näidete all olevaid paranduskommentaare, aga nagu elu näitab, tasub ka näited korras hoida, sest kommentaare ja standardeid vahest ei kiputa liialt hoolikalt lugema.

      kommentaar kirjutas Aulo Aasmaa — 2014-04-10 @ 18:51:36 | Vasta


RSS feed for comments on this post. TrackBack URI

Lisa kommentaar

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Muuda )

Twitter picture

You are commenting using your Twitter account. Log Out / Muuda )

Facebook photo

You are commenting using your Facebook account. Log Out / Muuda )

Google+ photo

You are commenting using your Google+ account. Log Out / Muuda )

Connecting to %s

Create a free website or blog at WordPress.com.