Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Personalausweisnummer generieren (https://www.delphipraxis.net/96367-personalausweisnummer-generieren.html)

Gehstock 23. Jul 2007 18:17

Re: Personalausweisnummer generieren
 
weiß der geier meine stimmt die(na gut muss ja net gültig sein) auch vieleicht findet ja jemand den Fehler

Polynom 23. Jul 2007 18:35

Re: Personalausweisnummer generieren
 
Ich würde mal die wage Vermutung äußern, dass es an der Funktion "TForm7.Cut" liegen könnte, denn: Ist es ausgeschlossen, dass die Zahl nicht auch 3-Stellig werden kann ??? Oder habe ich das Prinzip des Ermitteln der Prüfstellen falsch verstanden ?

Gehstock 23. Jul 2007 19:34

Re: Personalausweisnummer generieren
 
Die Maximale Zahl kann nur 9*7 sein also 63

TwoFace 23. Jul 2007 22:34

Re: Personalausweisnummer generieren
 
Hab ne 0 statt ner 4
*nurmalsoindenraumwerf*

MaBuSE 23. Jul 2007 23:09

Re: Personalausweisnummer generieren
 
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:

Zitat von Gehstock

Ich habe Dir mal den Algorithmus in Pascal geschrieben.
Ich habe versucht ihn möglichst einfach und leicht zu verstehen zu implementieren.
Man kann den Algorithmus natürlich an vielen Stellen noch optimiern.
(Macht mir das nicht zum Vorwurf. Außerdem ist es schon spät, ich bin müde.)

Das Beispielprogramm hat eine Funktion um die Prüfziffer aus einem String zu berechnen.
Delphi-Quellcode:
...
const
  // Die Gewichtung ist 7, 3, 1
  // Hier als 1, 7, 3 abgelegt, da der 1. Zugriff mit Gewichtung[1] erfolgt.
  Gewichtung : Array[0..2] of Integer = (1, 7, 3);

// getPZ berechnet die Prüfziffer zu der angegebenen Ziffernfolge
function TForm1.getPZ(s: string):string;
var
  i: Integer;
  x: Integer;
begin
  x := 0;
  for i := 1 to length(s) do
  begin
    x := x + StrToInt(s[i]) * Gewichtung[i mod 3];
  end;
  Result := IntToStr(x mod 10);
end;
....
Es gibt jede Menge TEdit Felder um die Behördenkennziffer (BKZ), Ausweisnummer (AWN), Geburtsdatum (GEBDAT) und Gültigkeitsdatum (GUEDAT) einzugeben. Es existieren auch leere Edit Felder in denen später die Prüfziffern (PZ) stehen.

Auf dem Button wird dann folgendes gemacht um die PZ Edit Felder mit den Prüfziffern zu füllen:
Delphi-Quellcode:
...
procedure TForm1.Button2Click(Sender: TObject);
begin
  ePZ1.Text := getPZ(eBKZ.Text + eAWN.Text);
  ePZ2.Text := getPZ(eGEBDAT.Text);
  ePZ3.Text := getPZ(eGUEDAT.Text);
  ePZ4.Text := getPZ(eBKZ.Text + eAWN.Text + ePZ1.Text +
                     eGEBDAT.Text + ePZ2.Text +
                     eGUEDAT.Text + ePZ3.Text);
end;
...
Das ist eigentlich schon alles.

Es existiert noch ein weiterer Button. Hier werden alle Zwischenwerte in ein Memo geschrieben, damit man sieht wie es funktioniert.
Delphi-Quellcode:
// Der selbe Algorithmus nur ausführlich kommentiert
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
  s: string;
  x, y, z: integer;
begin
  Memo1.Lines.Clear;
  Memo1.Lines.Add('Beispiel');
  Memo1.Lines.Add('Berechne Prüfziffer für BKZ ('+eBKZ.Text+') und AWN ('+eAWN.Text+')');
  x := 0;
  // Es soll die Prüfsumme über die BKZ und die AWN gebildet werden
  s := eBKZ.Text + eAWN.Text;

  // Für jede Ziffer einen Schleifendurchlauf
  for i := 1 to 9 do
  begin
    // y ist die aktuelle Ziffer
    y := StrToInt(s[i]);
    // z ist die Ziffer mal der Gewichtung
    z := y * Gewichtung[i mod 3];
    // x ist die Summe aller z
    x := x + z;
    // Ausgabe im Memo
    Memo1.Lines.Add(
      IntToStr(y)+ ' * ' +
      IntToStr(Gewichtung[i mod 3]) + ' = ' +
      IntToStr(z) );
  end;
  // Die Prüfziffer ist die Letzte Ziffer der Summe aller z
  Memo1.Lines.Add('');
  Memo1.Lines.Add('Summe aller z = ' + IntToStr(x));
  Memo1.Lines.Add('Prüfziffer ist die letzte Ziffer');
  Memo1.Lines.Add('PZ = '+IntToStr(x mod 10));
end;
...
Man kann auch folgende Zeile in die Funktion getPZ einbinden um sich die Zwischenwerte anzusehen.
Delphi-Quellcode:
...
// In Function TForm1.getPZ kann in der Schleife folgende Zeile benutzt werden
// um das Memo zu füllen
Memo1.Lines.Add(s[i]+' '+IntToStr(Gewichtung[i mod 3])+' '+IntToStr(StrToInt(s[i]) * Gewichtung[i mod 3]));
...
Im Anhang findet Ihr die Project1.exe zum testen, sowie den Quelltext.

Viel Spaß
MaBuSE

MaBuSE 23. Jul 2007 23:26

Re: Personalausweisnummer generieren
 
Zitat:

Zitat von MaBuSE
Delphi-Quellcode:
... i mod 3 ...

Falls Du nicht weißt was mod macht. hier eine kleine Erklärung:
Bei dem Datentyp Integer gibt es ja keine Nachkommastellen, es sind ja "nur" die ganzen Zahlen.
Wenn man jetzt Dividieren (durch x teilen) möchte, gibt es ein Ergebis der Division und den Rest.

Beisp:
  • 0 geteilt durch 3 ist 0 mit dem Rest 0 (0 mal 3 plus 0 = 0)
    1 geteilt durch 3 ist 0 mit dem Rest 1 (0 mal 3 plus 1 = 1)
    2 geteilt durch 3 ist 0 mit dem Rest 2 (0 mal 3 plus 2 = 2)
    3 geteilt durch 3 ist 1 mit dem Rest 0 (1 mal 3 plus 0 = 3)
    4 geteilt durch 3 ist 1 mit dem Rest 1 (1 mal 3 plus 1 = 4)
    5 geteilt durch 3 ist 1 mit dem Rest 2 (1 mal 3 plus 2 = 5)
    6 geteilt durch 3 ist 2 mit dem Rest 0 (2 mal 3 plus 0 = 6)
    7 geteilt durch 3 ist 2 mit dem Rest 1 (2 mal 3 plus 1 = 7)
    ...
In Delphi sieht das dann so aus:
Delphi-Quellcode:
...
var
  Ergebnis: Integer;
  Rest: integer;
begin
  Ergebnis := 5 div 3; // Ergebnis ist nun 1
  Rest := 5 mod 3;     // Rest ist nun 2
end;
...
So einfach ist das.

Die letzte Ziffer einer Zahl bekommt man mit:
Delphi-Quellcode:
...
  letzteZiffer := Zahl mod 10;
...
Wenn Du eine Zahl durch 10 teilst ist der Rest immer die letzte Ziffer.

Ich hoffe das hilft Dir.
Gute Nacht
MaBuSE

Luckie 24. Jul 2007 00:18

Re: Personalausweisnummer generieren
 
Zitat:

Zitat von MaBuSE
Wenn Du eine Zahl durch 10 teilst ist der Rest immer die letzte Ziffer.

Kleine Korrektur meinerseits:
Zitat:

Wenn Du eine Zahl im Dezimalsystem durch 10 teilst, ist Rest immer die letzte Ziffer.
Und etwas genauer und für alle Zahlensystem gültig:
Zitat:

Der Rest ist der nicht ganzzahlig teilbare Anteil der Division.
13 : 10 = 1 x 10 + 3
Die zehn "geht" einmal in die 13. Es bleibt drei "übrig". Die drei ist nicht mehr ganzzahlig druch zehn teilbar. Der Rest ist also drei.

Matze 24. Jul 2007 05:42

Re: Personalausweisnummer generieren
 
Kleine Anmerkung: MaBuSEs Code funktioniert bei mir einwandfrei.

MaBuSE 24. Jul 2007 06:35

Re: Personalausweisnummer generieren
 
Zitat:

Zitat von Luckie
Kleine Korrektur meinerseits

Ich bezog mich auf das Beispielprogramm oben und außerdem war ich völlig übermüdet (bin ich immer noch) ;-)

Zitat:

Zitat von Gehstock
@marabu bei deinen Code seh ich erstmal gar nicht durch die Hälfte deiner Befehle kenn ich noch nichteinmal aber ich verspreche , mich damit ausführlich zu beschäftigen

Das wollte ich vermeiden.

@Gehstock: Und dafür ist es verständlich genug, oder?

Zitat:

Zitat von Matze
Kleine Anmerkung: MaBuSEs Code funktioniert bei mir einwandfrei.

Danke, bei mir auch :mrgreen:

marabu 24. Jul 2007 12:23

Re: Personalausweisnummer generieren
 
Hallo,

ich hatte gestern scheinbar fortgesetzt massive Konzentrationsprobleme beim Lesen der Beispieltabelle auf der angegebenen Referenzseite, deshalb hier eine Korrektur meiner Funktion aus Beitrag #6. Dass ich nicht aufmerksamer gelesen hatte, lag übrigens daran, dass meine ersten (fehlerhaften) Funktionen mit den mir zur Verfügung stehenden Testdaten zufällig das richtige Ergebnis produzierten.

Delphi-Quellcode:
function ValidIdCardNumber(const s: string): Boolean;
var
  i, iSkip, iWeight, iSum: Integer;
begin
  Result := Length(s) = 36;
  if not Result then Exit;
  iSum := 0;
  iSkip := 0;
  for i := 1 to 35 do
  begin
    iWeight := Pred(2 shl (2 - Pred(i - iSkip) mod 3));
    if s[i] in ['0'..'9']
      then Inc(iSum, (Ord(s[i]) - Ord('0')) * iWeight)
      else Inc(iSkip);
  end;
  Result := iSum mod 10 = Ord(s[36]) - Ord('0');
end;
Die Berechnung des korrekten Gewichtes ist etwas undurchsichtig und entspringt einfach der Beobachtung, dass wenige triviale Abbildungen von (0,1,2) über (8,4,2) nach (7,3,1) führen. Ein vorbelegter Vektor à la MaBuSE ist da letzten Endes die bessere Lösung. Das sollte aber auch die einzige schwer nachvollziehbare Stelle in meiner Funktion sein.

Verlegene Grüße vom marabu


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:46 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz