Autor |
Beitrag |
oPPi
      
Beiträge: 66
MS Win 7 Pro, WinXP Pro
D3 Pro, TurboDelhi, Kylix 3 Pro
|
Verfasst: So 20.10.02 02:48
Hallo,
Ich hab von meinem Dotzenten ne Aufgabe hingeschnissen bekommen die mir einiges Kopfzerbrechen  bereitet.
Ich habe ein RichEdit1, RichEdit2, Button_Codiere, Button_Decodiere.
Jetzt zu meinen Problem:
Ich gebe Text in das RichEdit1 ein, dieser soll dann wenn ich den Button_Codiere betätige verschlüsselt werden nach dem Schlüssel:
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 <- Klartext
Q A Y W S X E D C R F V T G B Z H N U J M I K O L P <- Geheimtext
(Diese Methode nennt sich Monoalphabetische Chiffrierung)
Ich hab das mal getestet mit der Function:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| function Search_And_Replace(RichEdit: TRichEdit; SearchText, ReplaceText: string): Boolean; var startpos, Position, endpos: integer; begin startpos := 0; with RichEdit do begin endpos := Length(RichEdit.Text); Lines.BeginUpdate; while FindText(SearchText, startpos, endpos, [stMatchCase])<>-1 do begin endpos := Length(RichEdit.Text) - startpos; Position := FindText(SearchText, startpos, endpos, [stMatchCase]); Inc(startpos, Length(SearchText)); SetFocus; SelStart := Position; SelLength := Length(SearchText); richedit.clearselection; SelText := ReplaceText; end; Lines.EndUpdate; end; end; |
Quelltext 1: 2: 3: 4: 5: 6:
| procedure TForm1.Button_VerschluesselnClick(Sender: TObject); begin RichEdit2.Text := RichEdit1.Text; Search_And_Replace(Richedit1, 'OldText', 'NewText'); MsgBox('Der Text wurde verschlüsselt !!!'); end; |
Das funktioniert auch soweit wenn ich für OldText u. NewText die entsprechenden Werte (siehe oben) einsetze. Oder gibt es da ne bessere
Lösung?
Der verschlüsselte Text soll mir dann im RichEdit2 ausgegeben werden.
Wenn ich den Button_Decodiere betätige soll mir der verschlüsselte Text wieder als Klartext im RichEdit1 ausgeben werden.
Ich wäre euch für eine schnelle Hilfe sehr verbunden.
Gruß
oPPi
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 20.10.02 05:36
Ich muß gestehen, ich habe mir da jetzt keinen großen Kopf gemacht, aber als erstes ist mir [StringReplace[/b] durch den Kopf geschwirrt. Mir dem Flag ReplaceAll sollte es eigentlich kein Problem sein.
|
|
Wolff68
      
Beiträge: 302
Erhaltene Danke: 1
WinXP home
D6 Prof
|
Verfasst: So 20.10.02 21:01
Wird nicht hinhauen Luckie.
Wenn er alle A durch Q ersetzt und später alle Q zu H ist das Chaos Perfekt...
Eine Lösung wäre es in zwei Durchläufen. Erst A durch Ord(Q)+128 ersetzen usw... dann alles wieder runtersetzen.
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| const Ursprung = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; const Schluessel = 'qaywsxedcrfvtgbzhnujmikolpQAYWSXEDCRFVTGBZHNUJMIKOLP'; .... procedure TForm1.Button1Click(Sender: TObject); var i : byte; puffer : string; begin puffer := Memo1.Text; For i := 1 to Length(Ursprung) do begin puffer := StringReplace(puffer, Ursprung[i], Chr(Ord(Schluessel[i])+128), [rfReplaceAll]); end; For i := 1 to Length(Ursprung) do begin puffer := StringReplace(puffer, Chr(Ord(Schluessel[i])+128), Schluessel[i], [rfReplaceAll]); end; Memo2.Lines.Clear; Memo2.Text := puffer; end; |
Zurück das ganze dann genauso.
Ein Problem gibt es dabei aber, wenn im Text Zeichen sind, die aus dem oberen ASCII-Bereich sind. In diesem Beispiel wird ein ä nach dem zurückübersetzen zu einem h 
_________________ "Der Mensch ist nicht was er sich vorstellt oder wünscht zu sein, sondern das was andere in ihm sehen."
|
|
oPPi 
      
Beiträge: 66
MS Win 7 Pro, WinXP Pro
D3 Pro, TurboDelhi, Kylix 3 Pro
|
Verfasst: So 20.10.02 22:13
Hallo,
@Wolff68:
Die Umlaute wie ä,ü,ö und Sonderzeichen aus der oberen ASCII-Tabelle werden nicht verwendet. Es geht nur um die von mir angegebenen Zeichen.
Ich werd deinen Code mal checken ob er für meine Bedürfnisse reicht -> ich hoffe es zu mindest. So wie ich das überblicken kann, macht es nen ganz Guten
Werd mich morgen nochmal melden ob's gereicht hat fürn Bienchen
Gruß
oPPi
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: So 20.10.02 22:28
Hi!
Geht's nicht auch so? Oder habe ich eine Anforderung an den Code übersehen? (Code kodiert, dekodieren geht dann halt genau andersrum)
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| const Ursprung = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; const Schluessel = 'qaywsxedcrfvtgbzhnujmikolpQAYWSXEDCRFVTGBZHNUJMIKOLP';
{...}
procedure TForm1.Button1Click(Sender: TObject); VAR i,position : INTEGER; begin memo2.text:=''; for i:=1 TO Length(memo1.Text) do begin position:=Pos(memo1.Text[i],ursprung); if position>0 then memo2.text:=memo2.text+schluessel[position] else memo2.text:=memo2.Text+memo1.text[i]; end; end; |
MfG,
Peter
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
oPPi 
      
Beiträge: 66
MS Win 7 Pro, WinXP Pro
D3 Pro, TurboDelhi, Kylix 3 Pro
|
Verfasst: So 20.10.02 23:09
Hallo,
@Peter Lustig
dein Code ist super - die Sonderzeichen werden normal dargestellt das ist zwar nebensächlich aber man kann halt auch diese dann verwenden.
Anders herum sieht das ganze dann so aus:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure TForm1.Button2Click(Sender: TObject); VAR i,position : INTEGER; begin memo1.text:=''; for i:=1 TO Length(memo2.Text) do begin position:=Pos(memo2.Text[i],Schluessel); if position>0 then memo1.text:=memo1.text+Ursprung[position] else memo1.text:=memo1.Text+memo2.text[i]; end; Memo2.Lines.Clear; end; |
Ich hab jetzt einige Foren durchforstet aber bislang nichts passendes gefunden.
Aber hier werden Sie geholfen ...
Ist vielleicht auch für andere User interessant ...
Gruß
oPPi
PS: @Wolff68 - Deine Bio auf deiner Website find ich interessant, haben fast die gleichen Daten nur das ich "1101" Month jünger bin.
_________________ ... Manchmal kommt man nicht auf die einfachsten Sachen obwohl
die Lösung ganz nah liegt ...
|
|
Wolff68
      
Beiträge: 302
Erhaltene Danke: 1
WinXP home
D6 Prof
|
Verfasst: So 20.10.02 23:41
Und wiedermal muß ich Peter recht geben. Ist sicherer wegen den Umlauten.
Das mit dem einzeln durchgehen der Zeichen ist auch das naheliegende, nur hab ich schon oft bemerkt, daß das recht langsam ist. Pos() und StringReplace() sind da irgendwie schneller durch.
Meine Schleifen laufen nur 2x von a bis Z und fertig.
_________________ "Der Mensch ist nicht was er sich vorstellt oder wünscht zu sein, sondern das was andere in ihm sehen."
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 21.10.02 01:47
Wolff68 hat folgendes geschrieben: | Wird nicht hinhauen Luckie.
Wenn er alle A durch Q ersetzt und später alle Q zu H ist das Chaos Perfekt...
|
Ich sagte, ja das ist mir so spontan durch den Kopf geschossen.
|
|
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 21.10.02 08:33
Mir ist spontan der HTML-Parser von other durch den Kopf geschossen. Damit gehst du in einem Durchgang durch den Text durch, hast aber die Möglichkeit, gezielt auf einzelne Zeichen (Chars) zu kontrollieren.
Das heißt, ist aus dem A erst mal ein Q geworden, springt er zum nächsten Zeichen, und das Chaos sollte nicht auftreten.
|
|
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 21.10.02 09:49
Hier mal mein Vorschlag - wie gesagt, auf der technischen Basis von others HTML-Parser. Der kommt ohne "pos" und "StringReplace" aus und ist auch bei größeren Texten recht flott.
Luckie wird´s vielleicht wissen, die anderen dürfen mir glauben ...
1: 2: 3: 4: 5: 6: 7: 8: 9: 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: 36:
| function CodeFunc(const szInString: AnsiString): AnsiString; const encodetable : string[26] = 'QAYWSXEDCRFVTGBZHNUJMIKOLP'; var pSrc, pResult : pchar; lc : char; begin SetLength(Result,0); if(length(szInString) = 0) then exit;
pSrc := pointer(szInString); if(pSrc = nil) or (pSrc^ = #0) then exit;
SetLength(Result,length(szInString)); pResult := pointer(Result); ZeroMemory(pResult,length(szInString));
while(pSrc^ <> #0) do begin case pSrc^ of 'A'..'Z': Move(encodetable[(byte(pSrc[0]) - 64)],pResult^,1); 'a'..'z': begin lc := CHR(byte(encodetable[byte(pSrc[0]) - 96]) + 32); Move(lc,pResult^,1); end; else Move(pSrc[0],pResult^,1); end;
inc(pResult); inc(pSrc); end; end; |
Zur Erklärung -
Der Buchstabe A hat ja bekanntlich den ASCII-Wert 65. Da auch in der ASCII-Tabelle die Buchstaben des Alfabets aufeinanderfolgen, können wir die passenden Schlüsselwerte in einem String der Reihe nach anordnen:
Quelltext 1: 2:
| const encodetable : string[26] = 'QAYWSXEDCRFVTGBZHNUJMIKOLP'; |
Bleiben wir beim Beispiel mit dem Buchstaben A -
Um nun an den passenden Codewert zu kommen, ziehen wir 64 ab
Quelltext
Diesen Wert Eins benutzen wir in der Anweisung:
Quelltext 1:
| Move(encodetable[(byte(pSrc[0]) - 64)],pResult^,1); |
um das entsprechende Zeichen in "encodevar", das sich an dieser Position befindet, in das Ergebnis (= den Rückgabewert der Funktion) zu kopieren. Und das erste Zeichen unseres Strings ist ein Q.
Und so fort: B hat den ASCII-Wert 66, minus 64 ergibt 2, das entspricht dem A im String ...
Bei den Kleinbuchstaben ist das Prinzip identisch, nur ist hier der Wert, den wir abziehen müssen, 96. Das kleine A hat ja den ASCII-Wert 97, und wir müssen ja wieder auf unsere erste Position kommen. Richtig? Gut, da wir dann aber einen Großbuchstaben haben, müssen wir dessen ASCII-Wert heranziehen und 32 addieren.
Wieder am Beispiel des A:
Quelltext 1: 2:
| a (97) - 96 = 1 (entspr. dem Q im String) Q (81) + 32 = 113 (entspr. dem ASCII-Wert von q) |
wzbw.
Ein Wort noch dazu:
Quelltext 1: 2:
| else Move(pSrc[0],pResult^,1); |
oPPi hat zwar gesagt, es werden nur die Buchstaben des Alfabets genutzt. Man sollte aber dennoch damit rechnen, dass mal ein anderes Zeichen angegeben wird. Also reichen wir alles, was durch unser Raster (A-Z,a-z) fällt, 1:1 an das Funktionsergebnis durch.
Für die Dekodierung können wir übrigens die selbe Funktion verwenden. Lediglich die Stringtabelle (var "encodestring") wäre durch diese hier:
Quelltext 1:
| 'BOIHGKNQVTWYURXZAJEMSLDFCP'; |
zu ersetzen. Ich empfehle aber, eine zweite Variable (var "decodetable") mit diesem Inhalt anzulegen und im Funktionskopf eine Bool-Variable zu ergänzen, die über Kodierung und Dekodierung entscheidet. Beispielsweise:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| function CodeFunc(const szInString: AnsiString; const Encode: boolean): AnsiString; const encodetable : string[26] = 'QAYWSXEDCRFVTGBZHNUJMIKOLP'; decodetable : string[26] = 'BOIHGKNQVTWYURXZAJEMSLDFCP'; { ... } 'A'..'Z': if(Encode) then Move(encodetable[(byte(pSrc[0]) - 64)],pResult^,1) else Move(decodetable[(byte(pSrc[0]) - 64)],pResult^,1);
'a'..'z': begin if(Encode) then lc := CHR(byte(encodetable[byte(pSrc[0]) - 96]) + 32) else lc := CHR(byte(decodetable[byte(pSrc[0]) - 96]) + 32); Move(lc,pResult^,1); end; { ... } |
Das war´s.
|
|
|