UNIX, Linux, Programare, Scripting, Retele
unix, linux, programare, script, hosting, server, retele
Lista Forumurilor Pe Tematici
UNIX, Linux, Programare, Scripting, Retele | Reguli | Inregistrare | Login

POZE UNIX, LINUX, PROGRAMARE, SCRIPTING, RETELE

Nu sunteti logat.
Nou pe simpatie:
geogeorgiana17
Femeie
25 ani
Arad
cauta Barbat
26 - 57 ani
UNIX, Linux, Programare, Scripting, Retele / Delphi / Tutorial Delphi - Verificator CNP Moderat de DarkByte
Autor
Mesaj Pagini: 1
DarkByte
Moderator

Inregistrat: acum 19 ani
Postari: 10
Datorita feedback-ului super multumitor primit la primul meu tutorial (la ora cand scriu asta doar Geo postase raspuns ), ma apuc de al doilea tutorial.

Asa ca, hai sa vedem cum putem verifica un CNP (cod numeric personal) in Delphi.
Orice CNP (tineti cont ca doar in Romania exista CNP, din cate stiu ) e format din 13 cifre (yeah... i'm feeling lucky ).

SAALLZZOONNNC
unde:
S= sex (1=barbat, 2=femeie, 3=barbat nascut inainte de 1900, 4=femeie before 1900, 5=barbat dupa 2000, 6=femeie dupa 2000)
AA= anul (2 cifre)
LL= luna
ZZ= ziua
OO= orasul
NNN= numar din registrul Starii Civile (posibil, nu e sigur)
C= cifra de control (MD5-ul )

Ok, acum ca stim astea, sa vedem care sunt conditiile ca un CNP sa fie valid.
1. Trebuie sa aiba exact 13 cifre
2. Luna nu poate avea o valoare mai mare de 12
3. Ziua nu poate avea o valoare mai mare de 31 (depinzand si de luna)
4. Valoarea orasului nu poate fi 0 si nici mai mare de 41
5. Cifra de control
Formula de calcul al cifrei de control se bazeaza pe un numar 279146358279, iar cifra se calculeaza astfel:
Primele 12 cifre din CNP se inmultesc fiecare cu cifra corespondenta din numarul de mai sus, iar aceste produse sunt adunate. Suma rezultata se imparte (intreg) la 11, din care impartire ne intereseaza doar restul.
Sunt doua cazuri:
  a) Restul este intre 0 si 9, caz in care e cifra de control
  b) Restul este 10, caz in care cifra de control e 1

Aici e lista judetelor, in ordinea necesara pentru validarea unui CNP
 
Lista judetelor (albabetic)

01    Alba
02    Arad
03    Arges
04    Bacau
05    Bihor
06    Bistrita-Nasaud
07    Botosani
08    Braila
09    Brasov
10    Buzau
11    Caras Severin
12    Calarasi
13    Cluj
14    Constanta
15    Covasna
16    Dambovita
17    Dolj
18    Galati
19    Giurgiu
20    Gorj
21    Harghita
22    Hunedoara
23    Ialomita
24    Iasi
25    Ilfov
26    Maramures
27    Mehedinti
28    Mures
29    Neamt
30    Olt
31    Prahova
32    Satu Mare
33    Salaj
34    Sibiu
35    Suceava
36    Teleorman
37    Timis
38    Tulcea
39    Vaslui
40    Vâlcea
41    Vrancea

Bun, de ajuns cu teoria, un pic de practica...

Porniti Delphi, bla bla...
Acum va zic de la inceput: faceti un director nou pe undeva (INTERZIS in Recycle Bin ), si salvati programul (care momentan face un NIMIC mare ).

Puneti pe forma un Edit, un Label si un Button (vezi tutorialul precedent, daca e ceva in neregula cu astea )
Selectati labelul, setati proprietatea Caption (in Object Inspector) sa fie "Introduceti CNP pentru verificare:" (sau orice altceva, dar sa fie inteligibil ).
Selectati butonul, Caption sa fie egal cu "Verificare CNP" (orice, vezi regula de mai sus). Cautati si proprietatea Default a butonului si setati-o pe True. Asta va face ca programul, atunci cand este apasat Enter, sa considere ca s-a vrut apasarea butonului (este default).
Selectati casuta text, din proprietatea Text stergeti tot.
Pe langa astea, care deja (teoretic) va sunt cunoscute, vom adauga un ComboBox (o casuta derulanta
, in care vom afisa erorile sau daca este valid CNP-ul.
In acest moment programul ar trebui sa semene (macar de departe) cu asta


Bun, sa incepem cu inceputul. Prima oara trebuie sa verificam daca are lungimea de 13 cifre si sa fie cifre.
Verificarea daca un sir de caractere are lungimea 13 (tineti minte ca Edit tine doar siruri de caractere, nu cifre) e foarte simpla:

Code:

If Length(sir) = 13 Then ...

Functia Length de mai sus este o functie care accepta un singur parametru de tip string (sir de caracter) si returneaza lungimea lui in caractere.
Tipul de date string are o lungime maxima de 255 de caractere si este stocat in 256 de octeti. Pe prima pozitie a sirului este lungimea sirului, apoi urmeaza caracterele componente ale acestuia.
Deci, de fapt, Length ne returneaza codul ASCII al primului caracter (care nu este folosit la nimic altceva).

Pentru a verifica daca sirul contine (sau nu) doar cifre, trebuie sa-l parcurgem, caracter cu caracter, si sa testam fiecare caracter. Pentru asta avem nevoie de o bucla (structura repetitiva) care sa ia, pe rand, fiecare caracter din sir.
Sintaxa FOR
For contor := valoare_initiala To valoare_finala Do comanda;
sau
For contor := valoare_finala DownTo valoare_initiala Do comanda;
Structura repetitiva FOR are 2 modalitati de folosire, prezentate mai sus. Prima are un contor crescator, cealalta are un contor descrescator.
De retinut ca NU este permisa (desi uneori compilatorul nu genereaza eroare) modificarea valorii contorului buclei.

Stiind acestea, sa vedem codul unei functii care verifica daca un sir contine numai cifre sau nu:

Code:

function OnlyDigits(s:string):boolean;
var i:byte;
    d:boolean;
begin
  d:=true;
  for i:=1 to length(s) do
    if not (s[i] in ['0'..'9']) then d:=false;
  result:=d;
end;

Tipul de date Boolean este tipul logic. Variabilele de acest tip pot lua doar valori True sau False. Denumit astfel dupa George Boole, inventatorul notiunii.
Practic, aceasta functie foloseste doua variabile, una intreaga si una logica, pentru a parcurge sirul, iar la primul caracter care se dovedeste a NU fi cifra, se muta variabila logica pe False, adica sirul NU contine DOAR cifre.
Rezultatul functiei este tocmai aceasta variabila logica (sirul S contine doar cifre ? True / False).
Acum, avand aceste lucruri terminate, sa vedem prima varianta a verificarii, de fapt ce face butonul Verifica cand e apasat. Tineti cont ca momentan verifica doar lungimea sirului si faptul ca aceste contine doar cifre.

Code:

function OnlyDigits(s:string):boolean;
var i:byte;
    d:boolean;
begin
  d:=true;
  for i:=1 to length(s) do
    if not (s[i] in ['0'..'9']) then d:=false;
  result:=d;
end;

procedure TForm1.Button1Click(Sender: TObject);
var s:string;
begin
  ComboBox1.Items.Clear;
  s:=Edit1.Text;
  if (Length(s)=13) and OnlyDigits(s)
    Then Begin
      ComboBox1.Items.Add('CNP Valid');
      Edit1.Color:=clWhite;
         End
    Else Begin
      If not OnlyDigits(s) then ComboBox1.Items.Add('CNP trebuie sa contina doar cifre');
      if not (Length(s)=13) then ComboBox1.Items.Add('CNP trebuie sa contina 13 cifre');
      Edit1.Color:=clRed;
         End;
  ComboBox1.ItemIndex:=0;
end;

Atentie: functia OnlyDigits va trebui scrisa complet (sau direct copiata) in codul sursa al programului. procedure TForm1.Button1Click va aparea in momentul in care dati dublu-click pe buton si veti adauga doar variabilele si codul.
Dupa cum vedeti in codul sursa al butonului, in caz de CNP eronat, vom colora casuta text Edit1 in rosu, pe care il refacem in alb cand se va introduce un CNP corect.

Acum sa verificam ca valoarea lunii sa fie corecta. Pentru asta, vom lua cifrele 4 si 5 impreuna si vom verifica sa fie mai mare decat 0 si mai mica sau egala cu 12.
Simplu, nu ? -->

Code:

function IsMonthOk(s:String):Boolean;
var luna:byte;
begin
  luna := StrToInt (Copy(s, 4, 2));
  IsMonthOk := (luna <= 12) and (luna <> 0);
end;

Intalnim din nou tipul logic, dar de data asta intalnim si tipul Byte. Este tot un tip intreg (ca si integer si longint din tutorialul trecut), dar este strict pozitiv. Plaja lui de valori este intre 0 si 255 ($00 si $FF).
Ce se intampla in functie ? Copiem (cu functia Copy) din sirul S, de la pozitia 4, doua caractere, adica al 4-lea si al 5-lea caracter (sper ca ma urmariti pe functie). Rezultatul functiei Copy este direct parametru al functiei StrToInt, care trannsforma cele 2 caractere intr-un numar.
Alta diferenta (intentionata) este modalitatea de returnare a rezultatului functiei. Avand in vedere ca rezultatul functiei poate fi doar True sau False, e clar ca e posibil ca rezultatul functiei sa fie o conditie (luna mai mica sau egala cu 12 SI luna sa fie mai mare ca 0).

Bun, am terminat si cu luna, verificarea zilei este asemanatoare:

Code:

function IsDayOk(s:String):Boolean;
var ziua:byte;
begin
  ziua := StrToInt (Copy(s, 6, 2));
  IsDayOk := (ziua <= 31) and (ziua <> 0);
end;

Singurele diferente sunt:
- am luat caracterele 6 si 7
- am verificat sa aiba valoarea maxim 31

Verificarea orasului este (din nou) identica, acum stiti ce trebuie modificat, deci asta o faceti singuri si-i veti da numele IsTownOk. Caracterele sunt (ca sa nu va chinuiti cu numaratul ) 8 si 9.

Acum, verificarea cifrei de control. Poata ca pare greu, dar sincer... nu e. Imi spuneti voi parerea voastra, dar acum sa continuam.
Nu cred ca are rost sa trec din nou prin explicatia care am dat-o la inceput, asa ca va voi prezenta direct codul sursa:

Code:

function IsControlDigitOk(s:string):Boolean;
const c : string = '279146358279';
var suma, rest : integer;
    i : byte;
begin
  suma := 0;
  For i:=1 to 12 do suma := suma + StrToInt(s[i])*StrToInt(c[i]);
  rest := suma mod 11;
  if rest = 10 then rest := 1;
  IsControlDigitOk := (IntToStr(rest) = s[13]);
end;

Aici am definit un sir de caracter (cel pentru verificare) in constanta (care se poate modifica, btw ) C, apoi am facut suma produselor, am calculat restul, care, daca a fost 10, i-am pus valoarea 1. Daca restul acesta este egal cu ultima cifra din CNP (a 13-a) atunci CNP-ul este corect. In mod normal, doar aceasta functie ar fi de ajuns... dar am sa va las pe voi sa va ganditi de ce nu e de ajuns

Acum, ajunsi la sfarsitul tutorialului, daca ati adaugat toate functiile si conditiile in codul sursa al butonului, ar trebui sa aveti un verificator de CNP functional.

Pentru ca sa fiu sigur ca m-ati urmarit , aveti aici sursa cu executabil cu tot

Observatii: v-am dat lista oraselor, ati putea modifica programul in asa fel incat, dupa ce a fost introdus un CNP corect, sa afiseze data nasterii (inclusiv anul cu 4 cifre !) si numele orasului. Nu e prea greu, stiti voi e banal

In continuare, Practice makes perfect


_______________________________________
Portal SkullBox
SkullBox Forum
IP Finder and web browser details revealer


pus acum 19 ani
   
ori
Newbi

Inregistrat: acum 16 ani
Postari: 1
Salut. Nu gasesc fisierul cu sursa si executabil (Tut_CNP.zip). Zice ca este sters. Cum pot intra in posesia lui.
Multam.

Modificat de ori (acum 15 ani)


pus acum 15 ani
   
Pagini: 1  

Mergi la