Wątek zablokowany 2015-12-16 13:45 przez Rev.

Sprawdzanie poprawnosci nr PESEL

0

Witam posiadam program, rozumiem cały kod i jego działanie z wyjątkiem jednej rzeczy, a mianowicie dlaczego odejmowane jest 48 od cyfry numeru PESEL? Czy byłby ktoś w stanie mi pomóc w tej kwestii?

Podpowiedź do mojego zadania:

Numer PESEL jest to 11-cyfrowy, stały symbol numeryczny, jednoznacznie identyfikujący określoną osobę fizyczną.
Zbudowany jest z następujących elementów:
• zakodowanej daty urodzenia
• liczby porządkowej
• zakodowanej płci
• cyfry kontrolnej
Data urodzenia
Numeryczny zapis daty urodzenia przedstawiony jest w następującym porządku: dwie ostatnie cyfry roku, miesiąc i dzień. Dla odróżnienia poszczególnych stuleci przyjęto następującą metodę kodowania:
• dla osób urodzonych w latach 1900 do 1999 – miesiąc zapisywany jest w sposób naturalny
• dla osób urodzonych w innych latach niż 1900 – 1999 dodawane są do numeru miesiąca następujące wielkości:
o dla lat 1800-1899 - 80
o dla lat 2000-2099 - 20
o dla lat 2100-2199 - 40
o dla lat 2200-2299 - 60
Przyjęta metoda kodowania miesiąca urodzenia pozwala na rozróżnienie 5 stuleci. Kolejne miesiące w poszczególnych stuleciach mają następujące numery:
Miesiąc Stulecie
1800 - 1899 1900 - 1999 2000 - 2099 2100 - 2199 2200 - 2299
Styczeń 81 01 21 41 61
Luty 82 02 22 42 62
Marzec 83 03 23 43 63
Kwiecień 84 04 24 44 64
Maj 85 05 25 45 65
Czerwiec 86 06 26 46 66
Lipiec 87 07 27 47 67
Sierpień 88 08 28 48 68
Wrzesień 89 09 29 49 69
Październik 90 10 30 50 70
Listopad 91 11 31 51 71
Grudzień 92 12 32 52 72
Przykładowo osoba urodzona 14 lipca 2002 roku ma następujący zapis w numerze ewidencyjnym:
0 2 2 7 1 4
Płeć
Informacja o płci osoby, której zestaw informacji jest identyfikowany, zawarta jest na 10. (przedostatniej) pozycji numeru PESEL.
• cyfry 0, 2, 4, 6, 8 – oznaczają płeć żeńską
• cyfry 1, 3, 5, 7, 9 – oznaczają płeć męską
Po zmianie płci przydzielany jest nowy numer PESEL.
Cyfra kontrolna i sprawdzanie poprawności numeru
Jedenasta cyfra jest cyfrą kontrolną, służącą do wychwytywania przekłamań numeru. Jest ona generowana na podstawie pierwszych dziesięciu cyfr. Aby sprawdzić czy dany numer PESEL jest prawidłowy należy, zakładając, że litery a-j to kolejne cyfry numeru od lewej, obliczyć wyrażenie
1a + 3b + 7c + 9d + 1e + 3f + 7g + 9h + 1i + 3j
Następnie należy odjąć ostatnią cyfrę otrzymanego wyniku od 10. Jeśli otrzymany wynik nie jest równy cyfrze kontrolnej, to znaczy, że numer zawiera błąd.
Uwaga implementacyjna - jeśli ostatnią cyfrą otrzymanego wyniku jest 0, w wyniku odejmowania otrzymamy liczbę 10, podczas gdy suma kontrolna jest cyfrą. Oznacza to tyle, że cyfra kontrolna winna być równa 0 (stąd dobrze jest wykonać na wyniku odejmowania operację modulo 10). W wyniku niezbyt precyzyjnego opisu na stronie MSW ten aspekt jest często pomijany i prowadzi do błędów w implementacji sprawdzania poprawności numeru PESEL.
Przykład dla numeru PESEL 44051401358:
14 + 34 + 70 + 95 + 11 + 34 + 70 + 91 + 13 + 35 = 101
Wyznaczamy resztę z dzielenia sumy przez 10:
101:10 = 10 reszta = 1
Jeżeli reszta = 0, to cyfra kontrolna wynosi 0. Jeżeli reszta ≠ 0, to cyfra kontrolna będzie uzupełnieniem reszty do 10, czyli w podanym przykładzie jest to cyfra 9.
10 - 1 = 9
Wynik 9 nie jest równy ostatniej cyfrze numeru PESEL, czyli 8, więc numer jest błędny.

Program:

#include <stdio.h>

char czypoprawny(char pes[]){
	int tab[11]={1,3,7,9,1,3,7,9,1,3};
	int a,suma=0;
	for(a=0;a<10;a++){
		suma=suma+(tab[a]* (pes[a]-48));
	}	
	suma=suma%10;
	suma=10-suma;
	suma+=48;
	if (suma!=pes[10]) return 0;	
	
}

char jakaplec(char pes[]){
	if (pes[9]%2==0) return 'k';
	else return 'm';
}

int main()
{
 char pesel[12];
 int poprawny;
 char plec;
 printf("Podaj pesel:");
 gets(pesel);
 poprawny=czypoprawny(pesel);
 if (poprawny==0)
 {
 printf ("Podany pesel jest niepoprawny!!!\n");
 return 1;
 }
 plec=jakaplec(pesel);
 if (plec=='k') printf("Kobieta\n"); else printf("Mezczyzna\n");   
 return 0;   
}
1

Dodaje się aby przekonwertować zmienną char na int.

0

Tak na chłopski rozum, do dlaczego akurat 48 i czy nie lepiej od razu stworzyć pesel jako zmienna int?? Nie bawić się tu w żadne "chary" Ma to jakieś ważne znaczenie?

0

Bo to powinno być nie 48 tylko '0'. Liczbowa wartość znaku '0' wynosi w kodowaniu ASCII właśnie 48.

suma=suma+(tab[a]* (pes[a]-'0'));

i czy nie lepiej od razu stworzyć pesel jako zmienna int?
A zmieścisz PESEL w zwykłym int? ;-)
Przyjęło się takie urzędowe identyfikatory przechowywać jako stringi a nie liczby - zwłaszcza że niektóre (akurat nie PESEL, ale np. NIP) mogą zawierać spacje albo kreski i to o więcej niż jednej istniejącej konwencji.

0
const int PeselDlugosc = 11;

int sprawdzPesel(const char pes[]) {
    static const int tab[PeselDlugosc]={
            1, 3, 7, 9, 1,
            3, 7, 9, 1, 3,
            1 
    };

    int a,suma=0;
    for(a=0;a<PeselDlugosc;a++){
        suma=suma+(tab[a]* (pes[a]-'0'));
    }    
    return (suma%10)==0;
}
0

pesel zmiescisz w long long int

1 użytkowników online, w tym zalogowanych: 0, gości: 1