[PHP] Walidacja danych, część 2

Data dodania wpisu: 28-05-2010

Jako obiecałem, tako piszę: walidacja danych, część 2;)

W tej partii przedstawię poprawną walidację numeru dowodu osobistego, z wykorzystaniem poprawnych wag kolejnych znaków w numerze.

Na wstępie krótkie omówienie sumy kontrolnej, samych wag w kodzie oraz odpowiedników liczbowych dla trzech pierwszych znaków numeru będących znakami alfabetu łacińskiego. Istotą walidacji jest sprawdzenie, czy suma kontrolna znaków 1-3 oraz 5-9 jest równa znakowi nr 4 (czyli pierwsza liczba w numerze dowodu osobistego).
Kolejnym znakom w numerze dowodu osobistego odpowiadają następujące wagi:
7, 3, 1, 0, 7, 3, 1, 7, 3

Każda litera z pierwszych trzech znaków posiada swój reprezentant liczbowy w tym algorytmie, które wyglądają następująco (tutaj od razu utworzymy tablicę, w której indeksom znakowym przypiszemy wartości reprezentantów liczbowych:

$letters = array('A'=>10,'B'=>11,'C'=>12,'D'=>13,'E'=>14,'F'=>15,'G'=>16,
                 'H'=>17,'I'=>18,'J'=>19,'K'=>20,'L'=>21,'M'=>22,'N'=>23,
                 'O'=>24,'P'=>25,'Q'=>26,'R'=>27,'S'=>28,'T'=>29,'U'=>30,
                 'V'=>31,'W'=>32,'X'=>33,'Y'=>34,'Z'=>35);

Kod odpowiedzalny za wykonanie walidacji jest z kolei następujący (wyjaśnienie poszczególnych operacji w komentarzach):

function validateIdentityId($value){
            $value = strtoupper(preg_replace("/[^A-Za-z0-9]/","",$value)); 
//usuwamy wszystkie zbedne znaczki
            if(strlen($value) != 9){ 
//jesli dlugosc numeru dowodu jest rozna od wymaganych 9 znakow, funkcja zwraca false
                return false;
            }
            for($i = 0; $i < 3; $i++){ 
//kolejno sprawdzamy pierwsze trzy znaki
                if(!in_array($value[$i],array_keys($letters))){ 
//jesli nie ma ktoregos w tablicy reprezentantow literowych, funkcja zwraca false
                    return false;
                }
            }
            for($i = 3; $i < 9; $i++){ 
//dalej sprawdzamy, czy pozostale znaki sa numeryczne
                if(!is_numeric($value[$i])){
                    return false; 
//jesli ktorys nie jest cyfra, funkcja zwraca false
                }
            }
            $weights = array(7, 3, 1, 0, 7, 3, 1, 7, 3); 
//tablica wag poszczegolnych znakow
            $sum = 0; //zerujemy sume kontrolna 
            for($i = 0; $i < 3; $i++){ 
//dla 3 liter tworzymy sume kontrolna bedaca mnoznikami kolejnych indeksow wag i reprezentantow liczbowych dla tych liter
                $sum += $weights[$i] * $letters[$value[$i]];
            }
            for($i = 4; $i < 9; $i++){ 
//kontynuujemy tworzenie sumy kontrolnej poprzez wymnozenie wag spod indeksow 4+ oraz wartosci numeru dowodu osobistego (cyfry 5-9)
                $sum += $weights[$i] * $value[$i];
            }
            $int = $sum % 10; 
//z sumy kontrolnej bierzemy reszte z dzielenia przez 10 (operacja modulo)
            $checksum = ($int == 10) ? 0 : $int; 
//jezeli otrzymujemy liczbe 10, za sume kontrolna przyjmujemy wartosc 0 (zero), w przeciwnym przypadku, otrzymana reszte z dzielenia
            if ($checksum == $value[3]){
                return true; 
//i wreszcie spradzamy - jesli otrzymana suma kontrolna jest rowna cyfrze kontrolnej w numerze (znak nr 4) to walidacja powiodla sie
            }
            return false;
        }
Przykład:
Dla numeru dowodu osobistego: ABC523456 suma kontrolna z wykorzystaniem wag oraz reprezentantów liczbowych wynosi:
(10*7) + (11*3) + (12*1) + (2*7) + (3*3) + (4*1) + (5*7) + (6*3) = 70 + 33 + 12 + 14 + 9 + 4 + 35 + 18 = 195
195 % 10 = 5
W numerze mamy jako 4 znak cyfrę kontrolną 5 (ABC523456).
Zatem 5=5 - z tego wynika, że numer dowodu osobistego ABC5123456 jest poprawny.

ZOBACZ TEŻ:
Walidacja danych, część 1
Walidacja danych, część 3
Walidacja danych, część 4

Komentarze

Ten wpis nie posiada jeszcze komentarzy

Comments closed...