![]() |
Personalausweisnummer generieren
Delphi-Quellcode:
wobei x die Stelle im Maskedit darstellt und y den wert der stelle
procedure TForm7.Button1Click(Sender: TObject);
var x,y:integer; i:Integer; begin i:=0; for x := 1 to Length(Edit1.Text) do begin y:=chartoint(Edit1.Text[x]); case x of 1:i:=y*7; 2:i:=y*3; 3:i:=y*1; 4:i:=y*7; 5:i:=y*3; 6:i:=y*1; 7:i:=y*7; 8:i:=y*3; 9:i:=y*1; 10:i:=y*7; //- // Ausgabeland //- 14:i:=y*3; 15:i:=y*1; 16:i:=y*7; 17:i:=y*3; 18:i:=y*1; 19:i:=y*7; 20:i:=y*3; //- 22:i:=y*1; 23:i:=y*7; 24:i:=y*3; 25:i:=y*1; 26:i:=y*7; 27:i:=y*3; 28:i:=y*1; end; i:=i+i;// Hier ist der Fehler weiß aber nicht warum er rechnet falsch zusammen end; Label1.caption:=InttoStr(i); Edit2.Text:=Cut(InttoStr(i)); end; Function TForm7.cut(a:string):string; begin if length(a)>1 then begin Result:=a[2]; end else Result:=a; end; function TForm7.CharToInt(C: Char):integer; begin Result := 0; if C = '0' then Result := 0; if C = '1' then Result := 1; if C = '2' then Result := 2; if C = '3' then Result := 3; if C = '4' then Result := 4; if C = '5' then Result := 5; if C = '6' then Result := 6; if C = '7' then Result := 7; if C = '8' then Result := 8; if C = '9' then Result := 9; end; aber schon bei der 1. Stelle rechnet er falsch die 1. Stelle im Maskedit ist z.B. 7 für stelle 1. Steht im Case der Multiplikator 7-> 7*7=49 Raus hat er aber 98 ![]() |
Re: Personalausweisnummer generieren
Wenn i 49 ist, macht die Zeile i:=i+i; daraus 98 ;), Du hättest auch i := i * 2 schreiben können. Außerdem kann man die Funktion CharToInt auch kürzen:
Delphi-Quellcode:
function CharToInt(const C: char): byte;
begin Result := 0; case C of '1'..'9': Result := Ord(C) - 48; end; end; |
Re: Personalausweisnummer generieren
Ers soll I von Stelle1. nehmen und mit Stelle2. addieren usw. und das für alle stellen
|
Re: Personalausweisnummer generieren
Dann nimm eine weitere Variable (z.B. erg), initialisiere diese mit 0 und addiere sie auf:
Delphi-Quellcode:
erg := erg + i;
|
Re: Personalausweisnummer generieren
Danke immer diese kleinigkeiten
|
Re: Personalausweisnummer generieren
Hallo Gehstock,
wenn du deinen Code fertig hast, dann kannst du mal vergleichen. Mehr als ein Dutzend Zeilen sind nicht nötig. EDIT: drei Fehler habe ich in meinem Code entdeckt. (1) Die Gewichte müssen in absteigender Folge angewandt werden. (2) Jeder Abschnitt muss wieder mit dem höchsten Gewicht starten. (3) Die Prüfziffern der Abschnitte tragen das Gewicht 1.
Delphi-Quellcode:
Grüße vom marabu
function ValidIdCardNumber(const s: string): Boolean;
var i, iPos, iSum, iWeight: Integer; begin Result := Length(s) = 36; if not Result then Exit; iSum := 0; iPos := 2; for i := 1 to 35 do if s[i] in ['0'..'9'] then begin if i in [10, 20, 28] then iWeight := 1 else iWeight := Pred(2 shl iPos); Inc(iSum, (Ord(s[i]) - Ord('0')) * iWeight); iPos := Pred(iPos + 3) mod 3; end else iPos := 2; Result := iSum mod 10 = Ord(s[36]) - Ord('0'); end; |
Re: Personalausweisnummer generieren
Liste der Anhänge anzeigen (Anzahl: 1)
So fertig kann bitte jemand testen Obs Klappt für meinen Perso rechnet er jetzt richtig das Beispiel vom Link nicht?
Delphi-Quellcode:
@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
procedure TForm7.Button1Click(Sender: TObject);
var x,y:integer; i,l:Integer; begin i:=0; l:=0; for x := 1 to Length(MaskEdit1.Text)do begin y:=chartoint(MaskEdit1.Text[x]); case x of 1:i:=y*7; 2:i:=y*3; 3:i:=y*1; 4:i:=y*7; 5:i:=y*3; 6:i:=y*1; 7:i:=y*7; 8:i:=y*3; 9:i:=y*1; 10:i:=y*7; //- // Ausgabeland //- 14:i:=y*3; 15:i:=y*1; 16:i:=y*7; 17:i:=y*3; 18:i:=y*1; 19:i:=y*7; 20:i:=y*3; //- 22:i:=y*1; 23:i:=y*7; 24:i:=y*3; 25:i:=y*1; 26:i:=y*7; 27:i:=y*3; 28:i:=y*1; end; l:=l+StrtoInt(Cut(InttoStr(i))); end; Edit2.Text:=Cut(InttoStr(l)); end; Function TForm7.cut(a:string):string; begin if length(a)>1 then begin Result:=a[2]; end else Result:=a; end; function TForm7.CharToInt(C: Char):integer; begin Result := 0; if C = '0' then Result := 0; if C = '1' then Result := 1; if C = '2' then Result := 2; if C = '3' then Result := 3; if C = '4' then Result := 4; if C = '5' then Result := 5; if C = '6' then Result := 6; if C = '7' then Result := 7; if C = '8' then Result := 8; if C = '9' then Result := 9; end; |
Re: Personalausweisnummer generieren
Die Prüfziffer errechnet dein Programm für meine Ausweisnummer falsch.
|
Re: Personalausweisnummer generieren
Für meine Ausweisnummer kommt eine andere Prüfziffer raus ... eine Null um genau zu sein (statt 6). Und ich hab meinen Personalausweis auf legalem Wege erhalten :-D .
|
Re: Personalausweisnummer generieren
Zitat:
|
Re: Personalausweisnummer generieren
weiß der geier meine stimmt
![]() |
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 ?
|
Re: Personalausweisnummer generieren
Die Maximale Zahl kann nur 9*7 sein also 63
|
Re: Personalausweisnummer generieren
Hab ne 0 statt ner 4
*nurmalsoindenraumwerf* |
Re: Personalausweisnummer generieren
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:
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:
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.
...
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; .... Auf dem Button wird dann folgendes gemacht um die PZ Edit Felder mit den Prüfziffern zu füllen:
Delphi-Quellcode:
Das ist eigentlich schon alles.
...
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; ... Es existiert noch ein weiterer Button. Hier werden alle Zwischenwerte in ein Memo geschrieben, damit man sieht wie es funktioniert.
Delphi-Quellcode:
Man kann auch folgende Zeile in die Funktion getPZ einbinden um sich die Zwischenwerte anzusehen.
// 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; ...
Delphi-Quellcode:
Im Anhang findet Ihr die Project1.exe zum testen, sowie den Quelltext.
...
// 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])); ... Viel Spaß MaBuSE |
Re: Personalausweisnummer generieren
Zitat:
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:
Delphi-Quellcode:
So einfach ist das.
...
var Ergebnis: Integer; Rest: integer; begin Ergebnis := 5 div 3; // Ergebnis ist nun 1 Rest := 5 mod 3; // Rest ist nun 2 end; ... Die letzte Ziffer einer Zahl bekommt man mit:
Delphi-Quellcode:
Wenn Du eine Zahl durch 10 teilst ist der Rest immer die letzte Ziffer.
...
letzteZiffer := Zahl mod 10; ... Ich hoffe das hilft Dir. Gute Nacht MaBuSE |
Re: Personalausweisnummer generieren
Zitat:
Zitat:
Zitat:
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. |
Re: Personalausweisnummer generieren
Kleine Anmerkung: MaBuSEs Code funktioniert bei mir einwandfrei.
|
Re: Personalausweisnummer generieren
Zitat:
Zitat:
@Gehstock: Und dafür ist es verständlich genug, oder? Zitat:
|
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:
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.
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; Verlegene Grüße vom marabu |
Re: Personalausweisnummer generieren
Zitat:
Jede einzelne Zahl wird mit 7, 3 oder 1 multipliziert. Und wie du richtigerweise gesagt hast ist die größtmögliche Zahl, die hierbei entstehen kann 63. Jetzt nimmt man die letzten Stellen dieser Zahlen und addiert sie (bei deinem Code entspricht die Variable "l" dieser Zahl). Das hierbei größte Ergebnis ist allerdings 216. (Wenn jede Zahl, welche mit 7 multipliziert werden muss 7 ist, jede, die mit 3 multipliziert werden muss 3 ist und wenn jede Zahl, welche mit 1 multipliziert werden muss 9 ist. Dann wären das 24 Zahlen mit dem Wert 9 = 216) Außerdem würde ich beim "case ... of"-Bereich noch ein "else i:=0;" einfügen. Dann funktioniert der Code bei meinem Personalausweis. |
Re: Personalausweisnummer generieren
Liste der Anhänge anzeigen (Anzahl: 1)
Ja hatte ich untedessen auch bemerkt mit der 216
Zitat:
Delphi-Quellcode:
Danke
procedure TForm7.Button1Click(Sender: TObject);
var x,y:integer; i,l:Integer; begin i:=0; l:=0; for x := 1 to Length(MaskEdit1.Text)do begin y:=chartoint(MaskEdit1.Text[x]); case x of 1:i:=y * 7; 2:i:=y * 3; 3:i:=y * 1; 4:i:=y * 7; 5:i:=y * 3; 6:i:=y * 1; 7:i:=y * 7; 8:i:=y * 3; 9:i:=y * 1; 10:i:=y * 7; //- // Ausgabeland //- 14:i:=y * 3; 15:i:=y * 1; 16:i:=y * 7; 17:i:=y * 3; 18:i:=y * 1; 19:i:=y * 7; 20:i:=y * 3; //- 22:i:=y * 1; 23:i:=y * 7; 24:i:=y * 3; 25:i:=y * 1; 26:i:=y * 7; 27:i:=y * 3; 28:i:=y * 1 else i:=0; end; l:=l+strtoint(cut(inttostr(i))); end; Edit2.Text:=cut(inttostr(l)); end; Function TForm7.cut(a:string):string; begin if length(a)>1 then Result:=a[2]; if length(a)>2 then Result:=a[3] else Result:=a; end; function TForm7.CharToInt(C: Char):integer; begin Result := 0; if C = '0' then Result := 0; if C = '1' then Result := 1; if C = '2' then Result := 2; if C = '3' then Result := 3; if C = '4' then Result := 4; if C = '5' then Result := 5; if C = '6' then Result := 6; if C = '7' then Result := 7; if C = '8' then Result := 8; if C = '9' then Result := 9; end; @marabu mod war eig net gemeint eher "Pred" |
Re: Personalausweisnummer generieren
Zitat:
Das sind die typischen TForm1-ButtonKlick Programmier. Wenn es wenigstens einen Hauch von funktionaler Programmierung hätte. Von Objektorientiertheit mal gar nicht zu reden. Die armen Anfänger, die immer wieder mit so einem Code "belastet" werden ... *seufz* (Ich gehörte auch mal dazu) |
Re: Personalausweisnummer generieren
mag sein aber ich bin am lernen und ich glaub kaum das dei Code am Anfang viel anders aussah
davon abgesehen bei einen Testprogramm bei den ich nur mahl wissen wollte ob und wie ich das hinbekomme reicht mir "Button1Click" zu. Nennt sich Aufwand und Nutzen |
Re: Personalausweisnummer generieren
Zitat:
Vielleicht sollte man in Zukunft TForm1 und ButtonClick Beispiele einfach verbieten :-) kannst froh sein, dass ich nicht der Boardbetreiber bin :lol: |
Re: Personalausweisnummer generieren
Üblicherweise sehen Projekte mit mehr als 1 Button und 2 Edits bei mir so aus
Delphi-Quellcode:
procedure TFormMain.btnCalcClick(Sender: TObject);
var sie:Integer; begin editPhonetyp.Visible:=false; btnReport.Visible:=false; memo1.clear; sie:=strtoint(Copy(editIMEI.Text,1,2)); if ed = false then begin Memo1.Lines.add('Insert IMEI first'); editIMEI.SetFocus; exit; end; if Length(editIMEI.Text) < 17 then begin Memo1.Lines.add('Insert IMEI first'); editIMEI.SetFocus; exit; end; CalkImei15; taco:=StrToInt(Copy(editIMEI.Text,1,6)+Copy(editIMEI.Text,8,2)); ADOQuery1.Close; if sie < 35 then begin ADOQuery1.SQL.Text := 'select * from Babt00'; Database; end; if sie = 35 then begin ADOQuery1.SQL.Text := 'select * from Babt35'; Database; end; if sie >= 36 then begin ADOQuery1.SQL.Text := 'select * from Babt36'; Database; end; end; procedure TFormMain.Timer1Timer(Sender: TObject); begin AlphaBlendValue := AlphaBlendValue + 3; Timer1.Enabled := AlphaBlendValue < 255; if AlphaBlendValue = 255 then editIMEI.SetFocus; end; procedure TFormMain.Database; begin ADOQuery1.Open; While Not ADOQuery1.Eof do begin if ADOQuery1.FieldByName('Feld1').asinteger =(Taco) then begin hst:= ADOQuery1.FieldValues['Feld2']; modell:=ADOQuery1.FieldValues['Feld3']; zula:=ADOQuery1.FieldValues['Feld4']; land:=ADOQuery1.FieldValues['Feld5']; end; ADOQuery1.Next; end; if i15=y then begin lblCheck.Font.Color := clgreen; lblCheck.Caption := 'Valid'; btnCorrect.enabled := False; end else if i15<>y then begin lblCheck.Font.Color :=clred; lblCheck.Caption := 'Invalid'; btnCorrect.enabled := True; end; if Length(hst) =0 then begin memo1.clear; memo1.Lines.add('Phone not found. Please Report your TAC '); memo1.Lines.add('and your Phonemodel '); editPhonetyp.Visible:=true; btnReport.Visible:=true; editPhonetyp.SetFocus; exit; end else memo1.Lines.add('IMEI : '+editIMEI.Text+' is '+lblCheck.Caption); memo1.Lines.add('Manufacturer :'+hst); memo1.Lines.add('Model :'+modell); memo1.Lines.add('Reg. :'+zula); memo1.Lines.add('Country :'+land); editIMEI.SetFocus; end; function TFormMain.GetEnv(Variable:string):string; var buffer:array[1..1024] of char; begin if GetEnvironmentVariable( pChar(variable) , @Buffer, Sizeof(buffer) )=0 then result:='' else result:=PathGetLongName(buffer); end; function TFormMain.PathGetLongName(const ShortPath: String): String; var GetLongPathName: TGetLongPathName; hKernel32: THandle; begin hKernel32 := LoadLibrary(kernel32); try GetLongPathName := GetProcAddress(hKernel32, 'GetLongPathNameA'); if not Assigned(GetLongPathName) then RaiseLastWin32Error; //RaiseLastOSError NT / RaiseLastWin32Error 9X SetLength(Result, GetLongPathName(PChar(ShortPath), nil, 0)); SetLength(Result, GetLongPathName(PChar(ShortPath), PChar(Result), Length(Result))); finally FreeLibrary(hKernel32); end; {end try/finally} end; |
Re: Personalausweisnummer generieren
Zitat:
mach Dir echt mal Gedanken, lese paar Bücher, oder such im Netz. Versuch mal als erstes, Deinen Code wiederzuverwenden, indem Du einfach mal ein neues Projekt erzeugst, und dort dasselbe integrieren willst. Aber bitte ohne copy und paste und mit völlig anderen Edit Feldern. Wenn Du das dann gemacht hast, weißt Du, wieviel Aufwand es ist, den Code zu ändern und wiederzuverwenden. Und vor allen Dingen wirst Du merken, wie schwer es ist, ihn fehlerfrei wiederzuverwenden. Die 3 Dinge: Layout - Logik und Datenhaltung immer voneinander trennen, da diese flexibel austauschbar sein müssen und sollen... |
Re: Personalausweisnummer generieren
Ach lass gut sein
|
Re: Personalausweisnummer generieren
wollte Dich nicht vergraulen, im Gegenteil ...
Du solltest Dir angewöhnen im TMainForm überhaut nix zu kalkulieren, das ist der falsche Platz dafür. Ich weiß, der Objektinspektor verführt zu solch einem schlechten Programmierstiel. Ein Klick ist ja leicht gemacht. In eine Form Unit kommt wirklich nur das allernötigste rein, was man irgendwie zum Anzeigen braucht. Da wird weder was berechnet, noch mit Daten irgendwas gemacht. Wenn Du mal auf eine andere Programmiersprache umsteigst, kannst Du mit Deinem Code noch nichtmal was gebrauchen, indem Du was umschreibst .. Weil, Du wirst dann alles neu machen .... |
Re: Personalausweisnummer generieren
Zitat:
ich bin der Meinung, das man erst mal lernen sollte auf eigenen Füßen zu stehen, als gleich mit dem gehen oder sogar rennen anzufangen. Das was Gehstock da macht ist schon in Ordnung, für den Anfang. Er muß ja erst mal verstehen, wie das Ganze überhaupt funktioniert und zusammenhängt. Wie willst Du z.B. Layout, Logik und Datenhaltung trennen, wenn Du noch gar nicht so genau weißt wie das eigentlich genau funktioniert. Du hast doch sicherlich auch nicht gleich mit Mutli Tier Anwendungen angefangen um die von Dir angesprochenen 3 Dinge auf 3 verschiedene PCs zu verteilen (Layout auf den Client, Logik in den Application Server und Daten in den SQL Server), sondern mit einem einfachen "Hello World". Und dort ist ja auch der "Hello World" String fest im Code verankert und nicht ausgelagert. Also erst mal den Leuten erlauben zu stehen, dann durch Beispiele (z.B. ![]() Zitat:
Jeder verwendet nur die Mittel die er kennt. So entstehen manchmal Lösungen die nicht optimal sind. Ich würde aber deshalb nicht von "belastenden" Code sprechen. Du solltest also lieber Beispiele nach meinem oben genannten Motto erstellen. Dann gibt es auch mehr "unbelastenden" Code: Zitat:
Das Zitat ist auf dem oben erwähnten Beitrag #15 in diesem Thema. Zitat:
Ich finde es gut, wenn Du versuchst Leuten zu helfen und Tips zu geben. Also versteh meine Antwort bitte nicht als dumme Anmache, sondern auch nur als freundlichen Hinweis, bzw. freundlich gemeinte Hilfe von mir. Danke |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz