Autor |
Beitrag |
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Fr 01.11.02 14:39
Hallo!
Ich bin gerade dabei eine ENIGMA-Maschine für die Minifacharbeit in der Stufe 11 zu schreiben.
Ich habe ein Eingabefeld (Memofeld), bei dem der eingegebene Char geprüft - und eventuell geändert bzw. nicht angezeigt - wird.
Der gegebenfalls kodierte Char (sollte) wird im Ausgabefeld (Memofeld) nach der Verschlüsselung ausgegeben.
Dann kommt die Verschlüsselung (und das Problem).
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: 25: 26: 27: 28:
| var Form1:TForm1; Walze1 : Array[1..78] of String = 'Q','N','1' , 'W','T','2' , 'E','B','3' , 'R','H','4' , 'T','P','5' , 'Z','V','6' , 'U','D','7' , 'I','J','8' , 'O','R','9' , 'P','X','10' , 'A','T','11' , 'S','L','12' , 'D','M','13' , 'F','Z','14' , 'G','A','15' , 'H','G','16' , 'J','O','17' , 'K','U','18' , 'L','C','19' , 'Y','I','20' , 'X','O','21' , 'C','W','22' , 'V','E','23' , 'B','K','24' , 'N','S','25' , 'M','Y','26');
implementation
procedure TForm1.KlartextKeyPress(Sender: TObject; var Taste: Char); var EingabeChar: Char; CharPosWalze1 : Integer; KodierterText : String; begin if Taste in ['a'..'z'] then Taste := Upcase(Taste); if not(Taste in ['A'..'Z', ' ', #13, #8]) then Taste := #0; {Überprüfung des Tastendrucks im 1.Memofeld}
EingabeChar := Taste; if EingabeChar in ['A'..'Z'] then begin EingabeChar := Walze1[1]; CharPosWalze1 := CharPosWalze1 + 3; if CharPosWalze1>76 then CharPosWalze1 := 1; end; {Kodierung nach Tastendruck und Überprüfung bei 'A'..'Z'} KodierterText := KodierterText + EingabeChar; Kodierung.Text := KodierterText; {Ausgabe des kodierten Buchstaben oder des nichtkodierten Zeichens} end;
end. |
Wenn EingabeChar als Char definiert wird, kommt EingabeChar := Walze1[1]; als "Char" und "String" inkompatibel.
Wenn EingabeChar als String definiert wird, kommt if EingabeChar in ['A'..'Z'] then begin als "String" und "Char" inkompatibel.
Wie kann ich das hinkriegen?
Plz Help Me!
|
|
CenBells
      
Beiträge: 1547
Win 7
Delphi XE5 Pro
|
Verfasst: Fr 01.11.02 14:53
probier es doch mit eingabeChar := Char(Walze[1]);
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Fr 01.11.02 16:32
Klappt mit beiden Einstellungen (EingabeChar : Char; oder EingabeChar : String) nicht.
Als String kommt bei: if EingabeChar in ['A'..'Z'] then begin "String" und "Char" inkompatibel.
Als Char kommt bei: EingabeChar := Chr(Walze1[1]); inkompatibele Typen.
Trotzdem Danke für deine Hilfe.
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Fr 01.11.02 16:50
Habe schnell mal ein bisschen herumgefummelt (AM PROGRAMM NATÜRLICH  ) und es muss EingabeChar := Chr(StrToInt(Walze1[1])); sein, damit es funktioniert.
Und schon das nächste Problem:
Wie kann ich Varablen vor dem Ausführen einer Prozedur einen Wert zuweisen
bzw.
Wie kann ich einer Variablen einer Wert zuweisen, den sie vor dem ersten Durchlauf der Prozedur hat und der sich danach jedesmal ändert?
Bitte wieder helfen! 
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Fr 01.11.02 17:36
Hi!
Ireniceus hat Char geschrieben. Nicht Chr. Das Chr nicht klappt ist logisch. Allerdings bezweifle ich, dass Deine Funktion wirklich den gewünschten Effekt hat. Selbst wenn das erste Zeichen von Walze1 eine Zahl ist (was in Deinem Beispiel nicht ist), ist diese Zahl in ein Char umgewandelt nicht die Zahl als Zeichen.
Zu Deinem Wert: ich würde die Walzenposition (um die es hier geht, oder?) in einer globalen Variable speichern, die Du im OnCreate-Ereignis auf 1 setzt.
MfG,
Peter
P.S.: Wieso ist der kodierte Buchstabe immer gleich Walze1[1]?
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Fr 01.11.02 17:52
Hallo!
Ja ist mein Fehler, habe mich einfach verlesen.
ob es mit meiner Lösung klappt, weiss ich nicht, weil ich halt das nächste problem habe (mit OnCreate ist mir auch gerade eingefallen und wollte es gerade reinposten  ).
Zu Zitat: | P.S.: Wieso ist der kodierte Buchstabe immer gleich Walze1[1]? |
ist folgendes zu sagen:
1) Ich bin Schüler der Stufe 11 eine Gymnasiums und wir haben zu Beginn des Schuljahres mit Delphi angefangen.
2) Allerdings machen wir Buttons, Images, Canvas etc.
3) Mein Programm ist eine Minifacharbeit und dafür brauche ich VIELE VIELE VIELE VIELE sachen, die wir im Unterricht nich machen.
3.1) Deshalb habe ich erstmal die Walze1[1] gesetzt. Mir ist dann auch aufgefallen, dass da irgendetwas falsch ist und habe es geändert, woraus sich dann das Problem mit OnCreate ergeben hat (das hatten wir natürlich auch nicht im Unterricht).
Danke für die Hilfe Peter und Ireniceus.
Wir werden uns bestimmt bald wiedersehen.  (Aua, nicht schlagen...aua  )
P.S.: Habe es gerade ausprobiert ... und es klappt auch mit Char nicht (es gibt wieder die oben genannten Fehler).
Mit Quelltext 1:
| EingabeChar := Chr(StrToInt(Walze1[CharPosWalze1-2])); | ist es auch nicht richtig, weil Quelltext 1:
| EingabeChar := Chr(StrToInt(Walze1[1])); { bedeutet EingabeChar := Chr(StrToInt(Walze1['Q'])) } | und das geht nicht.
Brauche weiterhin Hilfe *seufz
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Fr 01.11.02 18:25
Wenn ich schreibe EingabeChar := Chr(Ord('Q')); dann klappt das Programm. Aber auch nur beim ersten Buchstaben, danach kann ich die Nachricht zwar noch weitertippen, aber es wird nicht mehr weiter verschlüsselt.
Mein Programm sieht momentan so aus (CharPosWalze1 hat im Moment keine Bedeutung und spielt keine Rolle) :
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: 37: 38: 39: 40: 41: 42: 43:
| var Form1:TForm1; CharPosWalze1 : Integer; Walze1 : Array[1..78] of String = ('Q','N','1' , 'W','T','2' , 'E','B','3' , 'R','H','4' , 'T','P','5' , 'Z','V','6' , 'U','D','7' , 'I','J','8' , 'O','R','9' , 'P','X','10' , 'A','T','11' , 'S','L','12' , 'D','M','13' , 'F','Z','14' , 'G','A','15' , 'H','G','16' , 'J','O','17' , 'K','U','18' , 'L','C','19' , 'Y','I','20' , 'X','O','21' , 'C','W','22' , 'V','E','23' , 'B','K','24' , 'N','S','25' , 'M','Y','26');
implementation
{$R *.dfm}
procedure TForm1.KlartextKeyPress(Sender: TObject; var Taste: Char); var EingabeChar : Char; KodierterText : String; begin if Taste in ['a'..'z'] then Taste := Upcase(Taste); {Wenn die Eingabe ein Kleinbuchstabe ist, dann wird sie zum Großbuchstaben} if not(Taste in ['A'..'Z', ' ', #13, #8]) then Taste := #0; {Wenn die Eingabe nicht Großbuchstabe, Leertaste, Enter oder Löschen ist, dann wird sie nicht aufgenommen}
EingabeChar := Taste; if EingabeChar in ['A'..'Z'] then begin EingabeChar := Walze1[1]; {Die Eingabe wird mit dem Buchstaben auf der 1. Walzenposition kodiert} CharPosWalze1 := CharPosWalze1 + 3; {Die Walzen dreht sich um einen Buchstaben weiter} if CharPosWalze1>78 then CharPosWalze1 := 3; {Nach 26 walzendrehungen ist die Walze wieder am Anfang} end; KodierterText := KodierterText + EingabeChar; Kodierung.Text := KodierterText; {Die Ausgabe wird um den verschlüsselten Buchstaben bzw. Leertaste, Enter oder Löschen erweitert} end;
procedure TForm1.FormCreate(Sender: TObject); begin CharPosWalze1 := 3; end;
end. |
Nachher soll das so aussehen: EingabeChar := Walze1[CharPosWalze1-2];.
Wieso kodiert das Programm nur beim ersten Buchstaben? Wie bekomme ich den String Walze1[1] in den Char EingabeChar ? Was mache ich hier überhaupt? Und Wer bin ich? Argggggh! Hilfe!
Bitte helft mir!
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Fr 01.11.02 18:42
Hi!
Ich habe mir Deine Verschlüsselungstabelle mal ein wenig genauer angeschaut und sehe zwei Probleme:
1. Wenn Du EingabeChar als Char beläst wirst Du damit nicht viel Freude haben. Spätestens wenn Du die '10' als einen einzigen Buchstaben behandeln willst, wird das nicht mehr funktionieren. Deklariere EingabeChar als String. Dann musst Du Deine dritte IF-Abfrage zwar etwas umschreiben, aber das ist ja kein großes Problem.
2. So wie das Programm jetzt da steht, kodiert es jeden Buchstaben mit Q, weil Walze1[1] nunmal ein Q ist. Ich kenne den Verschlüsselungsalgorithmus nicht genau, aber ich würde es mit Walze1[CharPosWalze1] versuchen. Je nach Algorithmus kann das aber auch falsch sein.
3. Du wirst beim dekodieren Probleme bekommen, wenn Du im kodierten Text die einzelnen Zeichen nicht irgendwie trennst. Wenn bespielsweise der kodierte Text '111' ist, weißt du momentan nicht, ob das '11' und '1' ist oder '1' und '11'. Oder verhindert der Entschlüsselungsalgorithmus das irgendwie?
MfG,
Peter
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Fr 01.11.02 19:16
 Ohohoh, da gibst aber ein großes Missverständnis (liegt vielleicht an mir)!
1. Der String Walze1 : Array[1..78] of String = ('Q','N','1' , 'W','T','2' , 'E','B','3' , ...); bedeutet folgendes:
Der Buchstabe 'Q' steht ein Position '1' der Walze und ist mit dem Buchstaben 'N' auf derselben Walze verbunden ('N' ist wichtig für Kodierungen bei mehreren Walzen. Aber erstmal mach ich das mit einer Walze)
2. Wegen CharPosWalze1 := CharPosWalze1 + 3; kommen beim Verschlüsseln nur die Zahlen (jeweils 3. "String" im Array) in die Variable CharPosWalze1, die ja eine Integervariable ist (da hast du irgendwie nicht richtig gelesen, oder Peter  ?). Nachher (wenn das Programm fertiger ist) soll die Variable EingabeChar etwa so "gefüllt" werden : EingabeChar := Walze1[CharPosWalze1-2];. Doch da weiss ich noch nicht, wie ich die Strindvariable (Walze1[CharPosWalze1-2]) in die Charvariable (EingabeChar) bekomme. Und CharPosWalze1-2 ist IMMER ein Buchstabe (1. ('Q'), 4. ('W'), 7. ('E') ... "String" im Array), also kann die nichtzweistellig sein Peter.
3. Mir ist klar das ich immer mit 'Q' kodiere(n sollte), aber es ist nur zur ÜBUNG (ich sage es nochmal: ich bin Schüler Stufe 11 und bin nicht so gut wie ihr) und leichter. Ich sage kodieren sollte, denn das Programm kodiert nur den ersten Buchstaben nicht weiter. Ich habe keine Ahnung weshalb.
4. Dekodieren will ich wahrscheinlich überhaupt nicht. Wenn doch, so siehe 2. .(Du hast dich nämlich verlesen oder etwas überlesen, Peter)
Mein Probleme im Moment ist:
1. Wie bekomme ich in die Charvariable EingabeChar die Stringvariable Walze1[1] (Ich nehme erstmal Walze1[1] weil das einfacher ist und nicht si viele Fehler auftreten können wie bei EingabeChar := Walze1[CharPosWalze1-2]).
2. Weshalb kodiert das Programm nur den ersten Buchstaben und alles?
 Bitte weiterhin helfen und, wenn etws unklar ist, fragen!
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Fr 01.11.02 20:29
Hi!
Okay, so langsam dämmert's bei mir!
Zu der Char-Variable:
Quelltext 1:
| EingabeChar:=Walze[1][1]; |
Damit sollte es klappen, wenn ich Dich nicht wieder falsch verstanden habe.
Zur Kodierung:
"KodierterText" ist eine lokale Variable der Prozedur. Jedes mal, wenn die Prozedur aufgerufen wird, wird sie neu initialisiert. Wenn Du sie global deklarierst und im OnCreate-Ereitnis initialisiert, sollte es funktionieren.
Wie kommt eigentlich später die Verbindung zwischen dem eingegeben Buchstaben und dem kodierten Buchstaben zustande? Im Moment sind die ja noch (gewollt) unabhänig.
MfG,
Peter[/code]
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Fr 01.11.02 20:34
MIr ist noch etwas aus meiner Pascalzeit (letztes und vorletztes Schuljahr) eingefallen.
Ich kann doch Delete- und Insert-Befehle benutzen, um die Walze weiter zu drehen.
Dann sieht der Quelltext so aus:
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:
| var Form1:TForm1; Walze1 : Array[1..52] of Char = ('Q','N' , 'W','T' , 'E','B' , 'R','H' , 'T','P' , 'Z','V' , 'U','D' , 'I','J' , 'O','R' , 'P','X' , 'A','T' , 'S','L' , 'D','M' , 'F','Z' , 'G','A' , 'H','G' , 'J','O' , 'K','U' , 'L','C' , 'Y','I' , 'X','O' , 'C','W' , 'V','E' , 'B','K' , 'N','S' , 'M','Y');
implementation
{$R *.dfm}
procedure TForm1.KlartextKeyPress(Sender: TObject; var Taste: Char); var EingabeChar : Char; KodierterText : String; begin if Taste in ['a'..'z'] then Taste := Upcase(Taste); {Wenn die Eingabe ein Kleinbuchstabe ist, dann wird sie zum Großbuchstaben} if not(Taste in ['A'..'Z', ' ', #13, #8]) then Taste := #0; {Wenn die Eingabe nicht Großbuchstabe, Leertaste, Enter oder Löschen ist, dann wird sie nicht aufgenommen}
EingabeChar := Taste; if EingabeChar in ['A'..'Z'] then begin EingabeChar := Walze1[1]; Insert(,,); Delete(,,); {Die Eingabe wird mit dem Buchstaben auf der 1. Walzenposition kodiert} end; KodierterText := KodierterText + EingabeChar; Kodierung.Text := KodierterText; {Die Ausgabe wird um den verschlüsselten Buchstaben bzw. Leertaste, Enter oder Löschen erweitert} end;
end. |
Das einzige Problem ist, dass ich die Delete- und Insert-Befehle in Dephi nicht so benutzen kann, wie ich es aus Pascal gewohnt bin (vielleicht stell ich mich auch zublöd an). Folgendermaßen sollen die Befhele benutzt werden:
1. Insert(die ersten beiden Stellen des Strings Walze1, Walze1, am Ende des Strings Walze1; d.h. Stelle 53 und 54gibt es noch nicht, da der String Walze1 nur 52 Stellen hat);
2. Delete(Walze1, die ersten beiden Stellen des Strings Walze1, 2);
Wie mach ich das? 
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Fr 01.11.02 20:57
Hi!
Dafür musst Du Dein Array Of Char in einen String umwandeln. Kannst Du das nicht direkt als String schreiben? Da es jetzt alles einzelne Buchstaben sind, sollte das doch gehen, oder?
Naja, wenn Du dann einen String hast, machst Du das so:
Quelltext 1: 2:
| Insert(Copy(text,1,2),text,Length(text)+1); Delete(text,Length(text)-1,2); |
MfG,
Peter
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Fr 01.11.02 21:02
Juhuuuuuu! Es klappt! DANKE (Jetzt gucke ich auch immer deine Sendung  )
DIESE ANTWORT BEZIEHT SICH AUF
Peter Lustig Fr 01.11.02 19:29
WICHTIG WICHTIG WICHTIG
Peter Lustig hat folgendes geschrieben: | Zur Kodierung:
"KodierterText" ist eine lokale Variable der Prozedur. Jedes mal, wenn die Prozedur aufgerufen wird, wird sie neu initialisiert. Wenn Du sie global deklarierst und im OnCreate-Ereitnis initialisiert, sollte es funktionieren. |
Doch ich verstehe nicht, warum ich sie initialisieren sollte! Was bringt das? Klappt auch, wenn ich sie nur als globale Variable definiere.
Peter Lustig hat folgendes geschrieben: | Wie kommt eigentlich später die Verbindung zwischen dem eingegeben Buchstaben und dem kodierten Buchstaben zustande? Im Moment sind die ja noch (gewollt) unabhänig. |
Ja, das ist so:
1. Entweder ich nehme eine Zählstelle in das Array mit auf, dann sieht das so aus:
Quelltext 1: 2: 3:
| Walze1 : Array[1..78] of String = ('Q','N','1' , 'W','T','2' , 'E','B','3' , 'R','H','4' , 'T','P','5' , 'Z','V','6' , 'U','D','7' , 'I','J','8' , 'O','R','9' , 'P','X','10' , 'A','T','11' , 'S','L','12' , 'D','M','13' , 'F','Z','14' , 'G','A','15' , 'H','G','16' , 'J','O','17' , 'K','U','18' , 'L','C','19' , 'Y','I','20' , 'X','O','21' , 'C','W','22' , 'V','E','23' , 'B','K','24' , 'N','S','25' , 'M','Y','26'); . . . EingabeChar := Walze1[1][1]; |
Bei EingabeChar müsste dann irgendwas um 3 erhöht werden (Aber ich verstehe nicht was Walze1[1][1] überhaupt bedeutet). Die Erhöhung sieht so aus:
eingegebener Buchstaben / kodierter Buchstabe / Walze1 (Buchstabe der rauskommt)
A / Q / (Walze1[1])
A / W / (Walze1[4])
A / E / (Walze1[7])
A / usw. / usw.
(verstanden?)
2. Oder ich nehme ins Array nur die Anordnung der Buchstaben auf der Walze und ihre jeweiligen "Partner"buchstaben auf der Walze auf. Das sieht dann so aus:
Quelltext 1: 2: 3: 4: 5:
| Walze1 : Array[1..52] of Char = ('Q','N' , 'W','T' , 'E','B' , 'R','H' , 'T','P' , 'Z','V' , 'U','D' , 'I','J' , 'O','R' , 'P','X' , 'A','T' , 'S','L' , 'D','M' , 'F','Z' , 'G','A' , 'H','G' , 'J','O' , 'K','U' , 'L','C' , 'Y','I' , 'X','O' , 'C','W' , 'V','E' , 'B','K' , 'N','S' , 'M','Y'); . . . EingabeChar := Walze1[1][1]; Delete(Walze1, die ersten beiden Stellen des Strings Walze1, 2); Insert(die ersten beiden Stellen des Strings Walze1, Walze1, am Ende des Strings Walze1; d.h. Stelle 53 und 54 gibt es noch nicht, da der String Walze1 nur 52 Stellen hat); |
Doch da weiss ich nicht, ob dein "Walze1[1][1]" noch geht und wie ich die Befehkle Delete und Insert richtig verwende (so wie in Pascal jedenfalls nicht!).
Das Array Walze1 würde sich dann so ändern:
eingegebener Buchstaben / kodierter Buchstabe / Walze1 (1. und 2. und vorletzte und letzte Stelle)
A / Q (Walze1[1]) / ('Q','N', ... ,'M','Y');
A / W (Walze1[4]) / ('W','T', ... ,'Q','N');
A / E (Walze1[7]) / ('E','B', ... ,'W','T');
A / usw. / usw.
(verstanden?)
 ...  ...  ...
Ziemlich kompliziert, oder? 
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Fr 01.11.02 21:17
Hi!
Initialisieren: stimmt, eigentlich kommst Du ohne aus. Aber irgendwie ist das eine Angewohnheit von mir, da immer auf Nummer sicher zu gehen.
D0P3 F!$H hat folgendes geschrieben: | Die Erhöhung sieht so aus:
eingegebener Buchstaben / kodierter Buchstabe / Walze1 (Buchstabe der rauskommt)
A / Q / (Walze1[1])
A / W / (Walze1[4])
A / E / (Walze1[7])
A / usw. / usw.
(verstanden?) |
Nicht ganz. Ich bin soweit, dass einBuchstabe nicht immer mit dem selben Buchstaben verschlüsselt werden soll. Das ist gut, da greift keine Häufigkeitsanalyse mehr. Aber was passiert, wenn ich 'B' drücke?
D0P3 F!$H hat folgendes geschrieben: | Aber ich verstehe nicht was Walze1[1][1] überhaupt bedeutet |
Also: Mit Walze1[1] greifst Du auf den String an Position 1 zu. String ist aber auch ein Array, bestehend aus Chars. Mit Walze1[1][1] greifst Du also auf das erste Zeichen des ersten Strings zu.
D0P3 F!$H hat folgendes geschrieben: | Doch da weiss ich nicht, ob dein "Walze1[1][1]" |
Da brauch es auch nicht mehr funktionieren. Da gibt die Walze1[1] ja schon einen Char. (Auch, wenn Du Walze1 vielleicht wirklich als String machst)
D0P3 F!$H hat folgendes geschrieben: | A / Q (Walze1[1]) / ('Q','N', ... ,'M','Y');
A / W (Walze1[4]) / ('W','T', ... ,'Q','N');
A / E (Walze1[7]) / ('E','B', ... ,'W','T');
A / usw. / usw.
(verstanden?) |
Das mit dem rotieren schon. Die Idee gefällt mir, erinnert an das Original. Aber wieder die Frage nach dem 'B'.
MfG,
Peter
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Sa 02.11.02 10:58
Hi!
Ich hab mir deine Antworten zu Herzen genommen und etwas ordentliches herausbekommen.
(obwohl du immer etwas neues gepostet hast, wenn ich gerade eine Antwort geschrieben habe. Schäm dich!  )
Mein Programm sieht jezt so aus:
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: 37: 38:
| var Form1 : TForm1; i : Integer; KodierterText, Walze1 : String;
implementation
{$R *.dfm}
procedure TForm1.KlartextKeyPress(Sender : TObject; var Taste : Char); begin if Taste in ['a'..'z'] then Taste := Upcase(Taste); {Wenn die Eingabe ein Kleinbuchstabe ist, dann wird sie zum Großbuchstaben} if not(Taste in ['A'..'Z', ' ', #13, #8]) then Taste := #0; {Wenn die Eingabe nicht Großbuchstabe, Leertaste, Enter oder Löschen ist, dann wird sie nicht aufgenommen}
if Taste in ['A'..'Z'] then begin KodierterText := KodierterText + Walze1[1]; {Die Eingabe wird mit dem Buchstaben auf der 1. Walzenposition kodiert} Insert(Copy(Walze1,1,2), Walze1, Length(Walze1)+1); Delete(Walze1, 1, 2); {Die ersten beiden Buchstaben der Walze werden an das Walzenende versetzt} end; case Taste of ' ', #13 : KodierterText := KodierterText + Taste; #8 : for i := 0 to Length(KodierterText)-1 do KodierterText[i] := KodierterText[i]; end; Kodierung.Text := KodierterText; {Die Ausgabe wird um den verschlüsselten Buchstaben bzw. Leertaste, Enter oder Löschen erweitert} end;
procedure TForm1.FormCreate(Sender : TObject); begin KodierterText := ''; Walze1 := 'QNWTEBRHTPZVUDIJORPXATSLDMFZGAHGJOKULCYIXOCWVEBKNSMY'; end;
end. |
Zu deiner Frage:
Peter Lustig hat folgendes geschrieben: | D0P3 F!$H hat folgendes geschrieben::
Die Erhöhung sieht so aus:
eingegebener Buchstaben / kodierter Buchstabe / Walze1 (Buchstabe der rauskommt)
A / Q / (Walze1[1])
A / W / (Walze1[4])
A / E / (Walze1[7])
A / usw. / usw.
(verstanden?)
Nicht ganz. Ich bin soweit, dass einBuchstabe nicht immer mit dem selben Buchstaben verschlüsselt werden soll. Das ist gut, da greift keine Häufigkeitsanalyse mehr. Aber was passiert, wenn ich 'B' drücke? |
Also das ist mein Fehler  . Aber ich will es dir erklären, wenn auch für mein jetziges Programm. OK? (Ich kanns dir auch für die ältere Version erklären, wenn du willst)
eingegebener Buchstaben / kodierter Buchstabe / Walze1 (Buchstabe der rauskommt) / Walze1 (1. und 2. und vorletzte und letzte Stelle)
? / Q / Walze1[1] / Walze1 = ('Q','N', ... ,'M','Y')
? / W / Walze1[1] / Walze1 = ('W','T', ... ,'Q','N')
? / E / Walze1[1] / Walze1 = ('E','B', ... ,'W','T')
? / R / Walze[1] / Walze1 = ('R','H', ... ,'E','B');
? / T / Walze[1] / Walze1 = ('T','B', ... ,'R','H');
? / usw. / Walze[1] / usw.
? / usw. / Walze[1] / usw.
? / usw. / Walze[1] / usw.
(verstanden?)
Und was für einen Buchstaben du eintippst (immer 'A' oder 'ABCDEFGHIJ' oder immer 'B'), das ist völlig egal.
Das müsste jetzt klar sein, oder?
Stehe aber für weitere Fragen gerne zur Verfügung.
Doch nun zu meiner nächsten Frage:
Das Eingabe- und das Ausgabefeld sind Memofelder. Ich habe ihnen eine vertikale ScrollBar gegeben, doch im Ausgabefeld bleibt der "Bildschrim" immer oben, wie kann ich ihn "mitweandern" lassen, was ja beim Eingabefeld funktioniert (liegt wahrscheinlich am Mauszeiger der ja immer ganz unter ist, oder?)
Ist doch eigentlich eine einfache Frage, oder? 
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Sa 02.11.02 12:13
Hi!
D0P3 F!$H hat folgendes geschrieben: | Schäm dich! |
*schaut beschämt zu Boden*
Wenn es völlig egal ist, welchen Buchstaben ich drücke, wie kann ich den Text dann wieder entschlüsseln (ich weiß, willst Du nicht machen, aber es müsste doch eigentlich möglich sein.)?
Was Dein Problem betrifft:
Quelltext 1: 2: 3: 4: 5:
| with memo2 do begin SelStart := Length(Text); SendMessage(memo2.Handle,EM_Scrollcaret,0,0); end; |
Quelltext 1:
| #8 : for i := 0 to Length(KodierterText)-1 do KodierterText[i] := KodierterText[i]; |
Was hat diese Zeile für einen Sinn? Du ersetzt jeden Buchstaben durch sich selbst? Außerdem: ein String fängt mit dem Index 1 an und endet mit Length(String).
MfG,
Peter
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Sa 02.11.02 13:25
Hi!
Zu deiner Frage:
Peter Lustig hat folgendes geschrieben: | Wenn es völlig egal ist, welchen Buchstaben ich drücke, wie kann ich den Text dann wieder entschlüsseln (ich weiß, willst Du nicht machen, aber es müsste doch eigentlich möglich sein.)? |
Bei der richtigen Enigma der Wehrmacht wurden die Anordnung der Walzen (vorderste Walze war z.B. Walze Nr.5, mittlere Nr.1 und letzte Nr.2) und die Buchstaben auf der jeweiligen Walze die "oben" (Ausgangsstellung) waren übermittelt (hier ein Link wo die gesamte Enigma SUPEr - besser als ich das kann  - erkärt ist: www-ivs.cs.uni-magde...er/enigma_index.html ). Wenn der Entschlüssler nun weiss, wie die Walzen anzuordnen und welche Buchstaben "oben" sind, dann tippt er die kodierte Nachricht ein und erhält den Klartext.
Zu deiner Lösung:
Peter Lustig hat folgendes geschrieben: | Was Dein Problem betrifft:
Quelltext 1: 2: 3: 4: 5:
| with memo2 do begin SelStart := Length(Text); SendMessage(memo2.Handle,EM_Scrollcaret,0,0); end; |
|
 Ähhh . . . muss ich das verstehen (BITTE erklären, schließlich muss ich das meinem Lehrer erklären können, wenn ich das einbaue)
Zu deiner nächsten Frage:
Peter Lustig hat folgendes geschrieben: |
#8 : for i := 0 to Length(KodierterText)-1 do KodierterText[i] := KodierterText[i];
Was hat diese Zeile für einen Sinn? Du ersetzt jeden Buchstaben durch sich selbst? Außerdem: ein String fängt mit dem Index 1 an und endet mit Length(String). |
Also mal wieder mein Fehler *rotwerdundkopfgegendiewandhämmer* (NICHT nachmachen Kinder, tut weh !!!)
Das ist mein nächstes Problem (hab ich vergessen zu erwähnen *heulundschäm*):
Bei der Verschlüsselung werden
1. ' ' (Leerstelle) erkannt und im Klartext auch als Leerstelle angezeigt und nicht verschlüsselt, sondern auch als Leerstelle ausgegeben (RICHTIG!)
2. #13 (Enter) zwar erkannt und im Klartext kommt auch ein Zeilensprung, aber in der Verschlüsselung als [] (so ein Kästchen ausgegeben) (FALSCH)
3. #8 (Löschen über Enter) zwar erkannt und im Klartext kann gelöscht werden, aber in der kodierten Nachricht passiert nichts. Z.B. wenn ich einen Text kodiere und dann ein Wort lösche und weiterschreibe, dann bleibt die kodierte Nachricht mit "gelöschtem" Wort stehen und es wird - wenn ich die Nachricht weiterschreibe - auch weiter kodiert (FALSCH)
Das #8 : for i := 0 to Length(KodierterText)-1 do KodierterText[i] := KodierterText[i]; sollte eigentlich bewirken, dass er den kodierten Text durch den kodierten Text MINUS die letzte Stelle ersetzt (er löscht also die letzte Stelle)
Ersezte ich Quelltext 1: 2:
| ' ', #13 : KodierterText := KodierterText + Taste; #8 : for i := 0 to Length(KodierterText)-1 do KodierterText[i] := KodierterText[i]; | durch das hier ' ', #13, #8 : KodierterText := KodierterText + Taste; dann wird wie bei "Enter" so ein Kästchen ([]) gemacht. Wenn ich es so lasse wie es ist, dann kommt kein Kästchen, aber er löscht die Stelle auch nicht.
wieder so kompliziert!
Wie kann ich das mit "Enter" und "Löschen" lösen?
Zuletzt bearbeitet von D0P3 F!$H am Mi 06.11.02 17:26, insgesamt 1-mal bearbeitet
|
|
Christian S.
      
Beiträge: 20451
Erhaltene Danke: 2264
Win 10
C# (VS 2019)
|
Verfasst: Sa 02.11.02 13:55
Hi!
D0P3 F!$H hat folgendes geschrieben: | Ähhh . . . muss ich das verstehen |
Nein, nicht wirklich. SendMessage wird verwendet, um Windowsnachrichten an Komponenten zu senden. Diese werden dann von dem Handle dieser Komponente empfangen und verarbeitet. EM_Scrollcaret ist die Nachricht, die wir in unserem Fall an Memo2.Handle senden wollen. Diese Nachricht veranlasst das Memofeld, soweit zu scrollen, dass der Cursor in Sicht ist. Und den haben wir mit SelStart:=Length(text) ans Ende gesetzt. Also scrollt EM_Scrollcaret das Memo bis ans Ende.
D0P3 F!$H hat folgendes geschrieben: | *rotwerdundkopfgegendiewandhämmer* |  So in etwa?
Quelltext 1: 2:
| #13: kodierter_text:=kodierter_text+#13#10; #8: Delete(kodierter_text,Length(kodierter_text),1); |
So könnte es funktionieren. Beim letzten bin ich mir nicht sicher, ob ich das mit den Nummern richtig hinbekommen hab, da verhaue ich mich jedes Mal. Und frag' mich bitte nicht, warum #10 dahinter muss. Ich habe nie rausgefunden, was das bedeutet, aber es funktioniert. Ach ja, muss beim Backspace auch die Walze zurückgedreht werden? Wenn ja, dann sollte das eigentlich wie das Vorspulen gehen.
MfG,
Peter
_________________ Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
|
|
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 02.11.02 14:13
Peter Lustig hat folgendes geschrieben: | Quelltext 1:
| #8: Delete(kodierter_text,Length(kodierter_text),1); |
So könnte es funktionieren. |
Hm, aber damit bist du auch aus dem Kodierschema "QWERT..." raus, Peter ... bzw. D0P3 F!$H. Mit jedem getippten Buchstaben verschiebst du die jeweils ersten beiden Buchstaben der Walze an das Ende:
Quelltext 1: 2:
| Insert(Copy(Walze1,1,2), Walze1, Length(Walze1)+1); Delete(Walze1, 1, 2); |
Logischerweise musst du das wieder rückgängig machen, wenn ein Buchstabe entfernt wird: Quelltext 1: 2: 3: 4: 5: 6: 7:
| #8: if(KodierterText <> '') then begin delete(KodierterText,length(KodierterText),1); Walze1 := copy(Walze1,length(Walze1)-1,2) + Walze1; delete(Walze1,length(Walze1)-1,2); end; |
Allerdings geht die ganze "Kodierung" auch einfacher und schneller. Man benötigt bloß die Positionsvariable, die man entsprechend anpasst, und kann sich das "copy" und "delete" an der Walze sparen:
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:
| const Walze1 : string = 'QNWTEBRHTPZVUDIJORPXATSLDMFZGAHGJOKULCYIXOCWVEBKNSMY'; var cText : string = ''; wPos : integer = 1;
procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: Char); begin if(Key in['a'..'z','A'..'Z',#13,#10,#32,#8]) then begin Key := UpCase(Key);
case Key of 'A'..'Z': begin cText := cText + Walze1[wPos]; if(wPos = length(Walze1) - 1) then wPos := 1 else inc(wPos,2); end; #13,#10,#32: cText := cText + Key; #8: if(cText <> '') then begin delete(cText,length(cText),1);
if(wPos = 1) then wPos := length(Walze1) - 1 else dec(wPos,2); end; end;
Memo2.Lines.Text := cText; end else Key := #0; end; |
Fertig.
Aber jetzt lese ich mir erst mal die Erklärungen zur echten ENIGMA durch, denn -sorry!- in dem Code von D0P3 F!$H sehe ich keinen Ansatz für eine Dekodierung. Insofern ist das für mich bestenfalls eine "Zeichensalatmaschine". 
|
|
D0P3 F!$H
Gast
Erhaltene Danke: 1
|
Verfasst: Sa 02.11.02 14:35
@ Peter Lustig:
1. Peter Lustig hat folgendes geschrieben: | Und frag' mich bitte nicht, warum #10 dahinter muss |
ICH BIN SCHLAUER WIE DU  hier stehts www.fh-jena.de/~gmue...s_halle/c_ascii.html  (müsste eigentlich stimmen)
2. Peter Lustig hat folgendes geschrieben: | Ach ja, muss beim Backspace auch die Walze zurückgedreht werden? Wenn ja, dann sollte das eigentlich wie das Vorspulen gehen. |
Das ist eine gute Frage. Weiss ich auch nicht, schätze aber mal, dass die dann die Nachricht neu tippen mussten (weil Walze "zurückdrehen" geht ja bei richtigen ENIGMA nicht so leicht schätze ich)
3. Ja jetzt klappt erstmal soweit.
@MathiasSimmack:
1. Muss mir mal dein Programm ansehen, ob ich das verstehe uns so.
2. ICH WIEDERHOLE MICH ZWAR UNGERN, ABER ... ich bin Schüler (Stufe 11) ... und dies ist meine Minifacharbeit in Informatik, dass heisst:
- Ich kann das Programmieren nicht so gut wie "richtige" Programmierer
- Ich fange mit einfaches Sachen an und arbeite mich dann zu Schwierigerem vor (mehr walzen, eventuell Steckbrett, Ring und Reflektor)
- Ich hatte nie vor und habe im Moment auch nicht vor, den Text wieder zu dekodieren (steht auch weiter oben in diesem Topic) D0P3 F!$H hat folgendes geschrieben: | 4. Dekodieren will ich wahrscheinlich überhaupt nicht. |
- Mein Lehrer hat wahrscheinlich keine Ahnung wie die Enigma programmiert wird, denn er meint, wenn ich die Enigma mit einer Walze hinkriege, wäre er schon erstaunt *g*. Also soll ich auch NICHT dekodieren. (hat er selbst gesagt)
Sorry, wenn ich auf dir rumhacke, aber ioch mache mir hier Mühe mir dem Programm und dann kommst du und machst es schlecht (wahrscheinlich ohne alles hier geschriebene zu lesen, sonst hätte ich dir zu widersprechen brauchen)!
ALSO nochmals:
!!! SORRY !!! @ MathiasSimmack @ !!! SORRY !!!
aber es war nötig
Zuletzt bearbeitet von D0P3 F!$H am Mi 06.11.02 17:27, insgesamt 1-mal bearbeitet
|
|
|