algorytm.org

Implementacja w Delphi/Pascal

Praca
Interesuje Cię praca przy weryfikacji oprogramowania do samolotów?
Sprawdź to!
Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Numer dowodu osobistego - Implementacja w Delphi/Pascal
Ocena użytkownikóww: *****  / 6
SłabyŚwietny
Nadesłany przez Tomasz Lubiński, 02 marca 2008 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

Dowod osobisty - Delphi/dowod.dpr:
// www.algorytm.org
// walidacja numeru dowodu osobistego
// Tomasz Lubinski (c) 2008

program dowod;
{$APPTYPE CONSOLE}
uses
  SysUtils;

var
letterValues: array[0..35] of Char =
   ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
    'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
    'U', 'V', 'W', 'X', 'Y', 'Z');

function getLetterValue(letter: Char): Integer;
var
   i: Integer;
begin
   result := -1;
   for i:=low(letterValues) to high(letterValues) do
      if letter = letterValues[i] then
      begin
         result := i;
         break;
      end;
end;

var
   id: String;
   i, checkSum: Integer;

begin

   //pobierz numer dowodu osobistego
   writeln('Podaj numer dowodu osobistego (bez spacji, myslinkow, itp)');
   readln(id);

   //sprawdz dlugosc podanego numeru
   if length(id) <> 9 then
   begin
      writeln('Nieprawidlowa dlugosc numeru');
      exit;
   end;

   //sprawdz czy podano 3 litery a nastepnie 6 cyfr
   for i:=1 to 3 do
      if getLetterValue(id[i]) < 10 then
      begin
         writeln('Nieprawidlowa seria dowodu');
         exit;
      end;
   for i:=4 to 9 do
      if (getLetterValue(id[i]) < 0) or (getLetterValue(id[i]) > 9) then
      begin
         writeln('Nieprawidlowy numer dowodu');
         exit;
      end;

   //sprawdz cyfre controlna
   checkSum := 7 * getLetterValue(id[1]);
   checkSum := checkSum + 3 * getLetterValue(id[2]);
   checkSum := checkSum + 1 * getLetterValue(id[3]);
   checkSum := checkSum + 7 * getLetterValue(id[5]);
   checkSum := checkSum + 3 * getLetterValue(id[6]);
   checkSum := checkSum + 1 * getLetterValue(id[7]);
   checkSum := checkSum + 7 * getLetterValue(id[8]);
   checkSum := checkSum + 3 * getLetterValue(id[9]);
   checkSum := checkSum mod 10;
   if checkSum <> getLetterValue(id[4]) then
      writeln('Podany numer dowodu jest niepoprawny')
   else
      writeln('Podany numer dowodu jest poprawny');

end.
Komentarze
photo
-1 # Neevor 2013-02-01 15:55
Ta pętla przeszukująca jest do zrobienia na jednym IFie.
if letter in ['A'..'Z'] then [...]
i potem wystarczy odjąć 55 (czy coś koło tego) od kodu ascii

Suma kontrolna liczona również bez sensu, można to zrobić w pętli, a wagi trzymać w tablicy.

Waga znaku nr 4 powinna wynosić 9, a tutaj nie jest sprawdzana.

Generalnie bardzo słaby kod i źle zapisany algorytm.
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
0 # Romek 2014-02-05 23:19
const
   letVal: array[1..36] of Char =
      '0123456789ABCDEFGHI JKLMNOPQRSTUVWX YZ';
     wagi: array[1..9] of integer = (7,3,1,9,7,3,1,7,3);

function getLetVal(znak: Char): Integer;
begin
     getLetVal := pos(UpCase(znak ),letVal) - 1;
end;

var id: String;
    i, suma: Integer;

begin
  writeln('Podaj numer dowodu osobistego');
  readln(id);

if length(id)<>9 then
  begin
     writeln('bledna dlugosc'); exit;
  end;
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
0 # Romek 2014-02-05 23:48
i ciąg dalszy:

for i:=1 to 3 do
   if (getLetVal(id)<10)
       OR (UpCase(id)='O') OR (UpCase(id)='Q') then
     begin
       writeln('bledna seria'); exit;
     end;
for i:=4 to 9 do
   if (getLetVal(id)<0) or (getLetVal(id)>9) then
     begin
       writeln('bledy w numerze'); exit;
     end;

suma := 0;
for i:=1 to 9 do
   suma := suma + wagi*getLetVal( id);

if (suma mod 10 <> 0)
     then writeln('bledny')
     else writeln('poprawny');
end.

Z punktu widzenia sprawdzania poprawności numeru nie ma znaczenia obliczanie cyfry kontrolnej - wystarczy, że suma iloczynów kończy się zerem.
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
-1 # Tomasz Lubiński 2013-02-04 08:28
Znak numer 4 to suma kontrolna!!!
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
0 # Romek 2014-02-05 23:34
formularz do komentarzy działa błędnie; niby pozwala wpisac 1000 znaków ale jak jest 900 to już wpisuje że ERROR_COMMMENT_ TOO_LONG
Odpowiedz | Odpowiedz z cytatem | Cytować
photo
0 # jaceku 2015-08-07 12:29
ja bym to zrobił o wiele prościej:

Function czySumaOk(nrdow :string);
const Litery:string[36]='ABCDEFGHIJKLMNO PQRSTUVWXYZ0123456789';
wagiLit:Array[1..36] of byte=(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28 ,29,30,31,32,33,34,35,
0,1,2,3,4,5,6,7,8,9);
waginrdow:array [1..9] of byte=(7,3,1,7,3,1,7,3,1);
var nrdokumOK:Boole an;
sumakontr:integ er;
begin
sumakontr:=0;
for i :=1 to 9 do
sumakontr:=sumakontr+byte( wagiLit[Pos(nrd okum,Litery)])* byte(waginrdow) ;

if StrToIntDef(cop y(linia1,10,1),-1)=(sumakontr mod 10) then
nrdokumOK:=True
else
nrdokumOK:=False;
end;
Odpowiedz | Odpowiedz z cytatem | Cytować
Dodaj komentarz