Codieren mit Passwort
Hi,
ich hab hier ein Problem. Bin noch Delphi Anfänger und hab Version 6. Also in der Schule haben wir die Aufgabe bekommen, einen Codierer zu erstellen, der den Text mit einem Passwort verschlüsselt. Das geht auch schon bei mir - fast. Es wird immer nur bis an die Stelle codiert, wo der Buchstabe im Passwort kommt. Also wenn man dann zB einen engliscen Text hat und als Passwort Ä setzt, geht alles. Mein Lehrer hat mir dann gesagt, ich soll die Verarbeitung in einem Array of Bytes machen. Da hab ich vorher noch nie mit gearbeitet und hab dementsprechend keine Ahnung, wie ich da ran gehe. Also momentan sieht mein Code so aus:
Delphi-Quellcode:
Wäre toll, wenn ihr mir das verbessern könntet und auch etwas erklären (wenn es nicht eh eindeutig ist ;) )
unit U_Codieren2;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Menus, StdCtrls, Buttons, ExtCtrls; type TForm1 = class(TForm) Memo1: TMemo; MainMenu1: TMainMenu; Datei1: TMenuItem; Neu1: TMenuItem; ffnen1: TMenuItem; Speicherals1: TMenuItem; Schlieen1: TMenuItem; OpenDialog1: TOpenDialog; SaveDialog1: TSaveDialog; Hilfe1: TMenuItem; Info1: TMenuItem; Btn_Codieren: TBitBtn; E_Passwort: TLabeledEdit; procedure Schlieen1Click(Sender: TObject); procedure Neu1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure ffnen1Click(Sender: TObject); procedure Speicherals1Click(Sender: TObject); procedure Info1Click(Sender: TObject); procedure Btn_CodierenClick(Sender: TObject); private Arbeit:Array [0..1000] of byte; { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Schlieen1Click(Sender: TObject); begin close; end; procedure TForm1.Neu1Click(Sender: TObject); begin Memo1.Clear; E_Passwort.Clear; end; procedure TForm1.FormCreate(Sender: TObject); begin Memo1.Clear; E_Passwort.Clear; end; procedure TForm1.ffnen1Click(Sender: TObject); begin if(OpenDialog1.Execute) then Memo1.Lines.LoadFromFile(OpenDialog1.FileName); end; procedure TForm1.Speicherals1Click(Sender: TObject); begin if SaveDialog1.Execute then Memo1.Lines.SaveToFile(SaveDialog1.FileName); end; procedure TForm1.Info1Click(Sender: TObject); begin // end; procedure TForm1.Btn_CodierenClick(Sender: TObject); var V_Text, V_Passwort:string; i, step,d:Integer; begin d:=0; V_Passwort:=E_Passwort.Text; V_Text:=Memo1.Text; for i:=1 to length(V_Text) do begin step:=Ord(V_Passwort[d]); d:=d+1; if d>length(V_Passwort) then d:=1; V_Text[i]:=char(step XOR Ord(V_Text[i])); Memo1.Text:=V_Text; end; end; end. Gruß |
AW: Codieren mit Passwort
|
AW: Codieren mit Passwort
Ob nun ArrayOfByte oder String ist egal.
In Delphi haben die String ein Feld für die Längenangabe, weswegen diesen bestimmte Steuerzeichen vollkommen egal sind. Vermutlich das selbe Problem: http://www.delphipraxis.net/154014-delphi-xor.html Dein Memo kann mit bestimmten Zeichen nicht so umgehn, wie du es möchtest. Sobald z.B. im Text, durch deine Kodierung, das Zeichen #0 vorkommt, dann bricht das Memo immer an dieser Stelle ab, da die #0 soviel wie "Ende" bedeutet. |
AW: Codieren mit Passwort
Scheint ganz so xD
In dem Thread sind ja doch schon ziemlich viele Änderungen. Ich fänds trotzdem toll, wenn das noch mal in einem Code gemacht werden könnte und nicht in sieben verschiedenen, die sich teilweise selbst widersprechen^^ Übrigens tolle Community habt ihr hier, wirklich! |
AW: Codieren mit Passwort
Wie schon beim Anderen gesagt:
Schau mal im Debugger, was wirklich in deinem V_Text drinsteht und nicht was im Memo angezeigt wird. Bei eurer XOR-Operation können Zeichen entstehen, mit welchen das Memo nunmal nicht korrekt (so wie ihr es wollt) umgehen kann und daran läßt nichts ändern. Ihr müßtest eure Verschlüsselung so ändern, daß solche Zeichen nicht entstehen können, aber dann ist es auch keine "direkte" XOR-Verschlüsselung mehr. Zum Testen kannst du ja einfach mal dieses machen;
Delphi-Quellcode:
und dazu noch dieses
Memo1.Text := AllesAnzeigen(V_Text);
Delphi-Quellcode:
Jetzt werden die "bösen" Steuerzeichen in einen Text "{nummer}" umgewandelt.
function AllesAnzeigen(S: String): String;
var i: Integer; begin Result := ''; for i := 1 to Length(S) do if S[i] >= ' ' then Result := Result + S[i] else Result := Result + Format('{%d}', [Ord(S[i])]); end; |
AW: Codieren mit Passwort
Man könnte das Problem aber minimieren, indem man einfach zum exklusiv veroderten Wert 32 addiert (beim Verschlüsseln) bzw. vor dem Verodern subtrahiert (beim Entschlüsseln), oder habe ich da einen Denkfehler drin?
|
AW: Codieren mit Passwort
Zitat:
Wenn man z.B. vor der Verschlüsselung nur ASCII-Zeichen zuläßt, dann wäre sowas möglich. Denn wenn man alles zuläßt, dann gibt es im Eingang 256 mögliche Zeichen und da diese einfachen XOR nur Zeichen in sich selbst kodieren, ergibt das im Ausgang ebenfalls alle 256 möglichen Zeichen und demnach sind auch solche Steuerzeichen möglich ... egal ob/wie man etwas dazurechnet. |
AW: Codieren mit Passwort
Hmmm... dann darf man das Ergebnis eben nicht als String interpretieren, nur wird es dann schwierig, das in einem Memo darzustellen :)
|
AW: Codieren mit Passwort
Es gibt doch diese "Zeichensätze" die nur die Zeichen A..Z und 0..9 enthalten, ich komme gerade nicht auf die korrekte Bezeichnung. Damit könnte man den Ursprungstext in der Darstellung schon einmal einschränken und dann noch einmal "verodern".
Gruß K-H |
AW: Codieren mit Passwort
Also wie gesagt: Mein Lehrer meinte, wir sollen das eigentliche Geschehen in einem Array of byte(s?) stattfinden lassen, weil das damit umgehen kann im Gegensatz zum Memo.
|
AW: Codieren mit Passwort
Zitat:
Selbst wenn du ein Byte-Array nimmst, wird es Probleme geben, sobald du das Ergebnis z.B. in einem Memo anzeigen willst. |
AW: Codieren mit Passwort
Wie wäre es denn mit einer modifizierten Darstellung?
etwa so:
Delphi-Quellcode:
Man kann das Ersetzen natürlich auch auf die "bösen" Zeichen beschränken (#0,#9,#10,#13.....)
AusString:='';
for i:=0 to mIndex do if BSTBbarray[i]<32 then AusString:=Ausstring+'.' else begin if BSTBarray[i]<128 then AusString:=Ausstring+char(BSTBarray[i]) else AusString:=Ausstring+'.'; end; Gruß K-H |
AW: Codieren mit Passwort
Zitat:
Aber wenn man nun diesen "angezeigten" Text versucht zurückzucodieren, dann geht das natürlich nicht, da man hierfür den "unveränderten" Text benötigt. |
AW: Codieren mit Passwort
Haben eben weiter gemacht in Informatik und neue Methoden kennen gelernt. Dadurch arbeite ich jetzt mit einem dynamischen Array of byte und muss dementsprechend auch mit Pointern umgehen.
Ich hab aber immer noch einen Fehler drin. Kann mir jemand das wirklich so verbessern, dass es bei diesen Wegen bleibt? Ich bin euch zwar dankbar für die Vorschläge, aber bitte bedenkt, dass ich noch nicht so viel Ahnung habe und macht es dementsprechend bitte auf einem einfach Level :P Hier noch mal mein aktualler Code
Delphi-Quellcode:
unit U_Codieren2;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Menus, StdCtrls, Buttons, ExtCtrls; type TForm1 = class(TForm) Memo1: TMemo; MainMenu1: TMainMenu; Datei1: TMenuItem; Neu1: TMenuItem; ffnen1: TMenuItem; Speicherals1: TMenuItem; Schlieen1: TMenuItem; OpenDialog1: TOpenDialog; SaveDialog1: TSaveDialog; Hilfe1: TMenuItem; Info1: TMenuItem; Btn_Codieren: TBitBtn; E_Passwort: TLabeledEdit; procedure Schlieen1Click(Sender: TObject); procedure Neu1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure ffnen1Click(Sender: TObject); procedure Speicherals1Click(Sender: TObject); procedure Info1Click(Sender: TObject); procedure Btn_CodierenClick(Sender: TObject); private Speicher:Array of byte; { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Schlieen1Click(Sender: TObject); begin close; end; procedure TForm1.Neu1Click(Sender: TObject); begin Memo1.Clear; E_Passwort.Clear; end; procedure TForm1.FormCreate(Sender: TObject); begin Memo1.Clear; E_Passwort.Clear; end; procedure TForm1.ffnen1Click(Sender: TObject); begin if(OpenDialog1.Execute) then Memo1.Lines.LoadFromFile(OpenDialog1.FileName); end; procedure TForm1.Speicherals1Click(Sender: TObject); begin if SaveDialog1.Execute then Memo1.Lines.SaveToFile(SaveDialog1.FileName); end; procedure TForm1.Info1Click(Sender: TObject); begin // end; procedure TForm1.Btn_CodierenClick(Sender: TObject); var V_Text, V_Passwort:string; i, step,d,N,len:Integer; begin d:=0; V_Passwort:=E_Passwort.Text; len:=length(Memo1.Text); getmem(speicher,len); FOR i:=1 TO len DO begin step:=Ord(V_Passwort[d]); d:=d+1; if d>length(V_Passwort) then d:=1; FOR N:=1 TO len DO speicher[N]:=ord(Memo1.Text)[N]; Speicher[i]:=char(step XOR Speicher[i]); end; end; end. |
AW: Codieren mit Passwort
Statt
Delphi-Quellcode:
nimmt man normalerweise
getmem(speicher,len)
Delphi-Quellcode:
. Die Zeile ist
setlength(speicher,len)
Delphi-Quellcode:
ein Artefakt, auf jeden aber falsch; denn i ist nicht definiert nach der for-Schleife (wenn überhaupt dann = len+1), und der char-Typecast ist bestenfalls überflüssig, besser wäre byte().
Speicher[i]:=char(step XOR Speicher[i])
Edit: Sehe gerade, daß
Delphi-Quellcode:
wohl noch in der i-Schleife liegt, also dann: sinnvoll einrücken und byte() statt char().
Speicher[i]:=char(step XOR Speicher[i])
|
AW: Codieren mit Passwort
Noch was:
Delphi-Quellcode:
Kannst du weglassen, da du das Memo im OI unter Lines leeren kannst und das Editfeld im OI unter Caption.
procedure TForm1.FormCreate(Sender: TObject);
begin Memo1.Clear; E_Passwort.Clear; end; Würd ich machen, das macht den Code kleiner und übersichtlicher. |
AW: Codieren mit Passwort
Du könntest das Byte-Array auch zum Ausgeben in Hexadezimal oder Base64 umwandeln:
Delphi-Quellcode:
// in etwa:
Memo.Text := ToHex(Encrypt(ToBytes(Memo.Text))); // vorausgesetzt: // - In Memo steht vorher der Klartext // - ToHex() wandelt ein Byte-Array in einen Hex-String um // - ToBytes() wandelt einen String in ein Byte-Array um // - Encrypt() verschlüsselt dann den Text |
AW: Codieren mit Passwort
seh ich genauso. wenn es base64 oder wie auch immer codiert ist, gibt es keine probleme bei der ausgabe im memo.
|
AW: Codieren mit Passwort
Zitat:
|
AW: Codieren mit Passwort
[edit]
ups verlesen |
AW: Codieren mit Passwort
Zitat:
|
AW: Codieren mit Passwort
Ich bin euch für eure Antworten wirklich dankbar, im Ernst!
Aber ich denke, ihr denkt dabei zu weit. Ihr müsst euch bitte in die Lage eines Schülers versetzen, der gerade erst Delphi kennen gelernt hat. Und dessen Lehrer erwartet nicht, dass er sämtliche Funktionen des Programms kennt, sondern dass das aus dem Unterricht umgesetzt wird. Also ich fände es wirklich nett, wenn ihr mehr auf das eingehen könntet, was ich bisher habe und nicht eure (wahrscheinlich) langjährige (Experten-)Erfahrung einbringen würdet. Geht das in Ordnung? Ich will jetzt auch nicht unverschämt wirken oder so. Hier haben wir übrigens nen Error im aktuellen Code: Zitat:
|
AW: Codieren mit Passwort
OK, hab grad n ziemlich dummen Fehler entdeckt, der mir einiges versaut hat :D
Delphi-Quellcode:
unit U_Codieren2;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Menus, StdCtrls, Buttons, ExtCtrls; type TForm1 = class(TForm) Memo1: TMemo; MainMenu1: TMainMenu; Datei1: TMenuItem; Neu1: TMenuItem; ffnen1: TMenuItem; Speicherals1: TMenuItem; Schlieen1: TMenuItem; OpenDialog1: TOpenDialog; SaveDialog1: TSaveDialog; Hilfe1: TMenuItem; Info1: TMenuItem; Btn_Codieren: TBitBtn; E_Passwort: TLabeledEdit; procedure Schlieen1Click(Sender: TObject); procedure Neu1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure ffnen1Click(Sender: TObject); procedure Speicherals1Click(Sender: TObject); procedure Info1Click(Sender: TObject); procedure Btn_CodierenClick(Sender: TObject); private Speicher:Array of byte; { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Schlieen1Click(Sender: TObject); begin close; end; procedure TForm1.Neu1Click(Sender: TObject); begin Memo1.Clear; E_Passwort.Clear; end; procedure TForm1.FormCreate(Sender: TObject); begin Memo1.Clear; E_Passwort.Clear; end; procedure TForm1.ffnen1Click(Sender: TObject); begin if(OpenDialog1.Execute) then Memo1.Lines.LoadFromFile(OpenDialog1.FileName); end; procedure TForm1.Speicherals1Click(Sender: TObject); begin if SaveDialog1.Execute then Memo1.Lines.SaveToFile(SaveDialog1.FileName); end; procedure TForm1.Btn_CodierenClick(Sender: TObject); var V_Passwort:string; i, step,d,N,len:Integer; begin d:=0; V_Passwort:=E_Passwort.Text; len:=length(Memo1.Text); getmem(speicher,len); FOR N:=0 TO len DO begin Speicher[N]:=ord(Memo1.Text[N]) end; FOR i:=1 TO len DO begin step:=Ord(V_Passwort[d]); d:=d+1; if d>length(V_Passwort) then d:=1; end; FOR N:=1 TO len DO begin Speicher[i]:=step XOR Speicher[i]; end; end; end. Wie muss ich jetzt weiter machen? |
AW: Codieren mit Passwort
Würdest du in der Zukunft bitte selber den Delphi-Tag für Delphicode nehmen?
|
AW: Codieren mit Passwort
Sorry, kannte die Funktion nicht^^
Hab den Code nach neuestem Stand aktualisiert. |
AW: Codieren mit Passwort
Ist jetzt nicht böse gemeint, aber wenn du mit unseren Hilfestellungen nicht zufrieden bist, weil dein Lehrer solche Lösungen nicht von dir erwartet. Warum fragst du dann uns und nicht deinen Lehrer? Denn dein Lehrer wird dir da eher sagen können, was du machen musst, damit es so ist, wie er es haben will.
Und so fragen wie "Was muss ich jetzt weiter machen?" sind nicht sonderlich hilfreich. Sag doch, was noch nicht funktioniert. Dann kann man dir besser helfen. Ich kann dir jetzt bei deinem Problem leider nicht weiterhelfen, da ich erstens nicht weiß, was du noch machen willst und ich zweitens hier auf Arbeit grad kein Delphi zur Verfügung habe um deinen Code zu testen, ob er noch Fehler beinhaltet. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:32 Uhr. |
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