Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Playfair Verschlüsselung


goog - Mi 12.01.05 19:22
Titel: Playfair Verschlüsselung
Hi Leute !

Bin noch ziemlich neu im Umgang mit Delphi! Was muss ich bei ner Prozedur beachten wenn ich Strings zurückgebe? Ich will das ein String auf doppelte Buchstaben untersucht wird, und wenn doppelte vorhanden sind, dann soll aus dem zweiten ein X werden. Trotzdem soll er noch erscheinen. Wenn die Länge ungerade ist soll noch ein X ran.

Beispiel:
MITTWOCH --> MITXTWOCHX

Was muss ich hier noch verändern?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure verschluessel (text:string);
var l,i:integer;
begin
l:=length(text);
for i:=1 to l do
 if text[i]=text[i+1then text[i+1]:='X';
 text[i]:=text[i];
end;


Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.


Delete - Mi 12.01.05 19:35

Entweder du übergibst den Parameter als var-Parameter oder du machst eine Funktion, was ich für sinnvoller erachten würde.


IngoD7 - Mi 12.01.05 20:28
Titel: Re: Parameterübergabe
goog hat folgendes geschrieben:
Beispiel:
MITTWOCH --> MITXTWOCHX

Was muss ich hier noch verändern?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure verschluessel (text:string);
var l,i:integer;
begin
l:=length(text);
for i:=1 to l do
 if text[i]=text[i+1then text[i+1]:='X';
 text[i]:=text[i];
end;


Vieles.

1.) Das kann nicht laufen, weil du auch den letzten Buchstaben mit dem letzten+1 vergleichst. Den letzten+1 gibt es aber nicht. :wink:

2.) Du vergleichst einen Buchstaben mit dem darauffolgenden. Sind sie gleich, verwandelst du den zweiten davon in ein X. Der zweite ist damit aber weg. Aus MITTWOCH würde MITXWOCH.

3.) text(i):=text(i) tut nicht so wirklich viel. :wink:

4.) Wenn 2.) nicht wäre und du tatsächlich das X einfügen würdest, würde dein String text aber verlängert, was wiederum bedeuten würde, dass deine for-Schleife nie bis an das (neue) Ende käme.

Mache eine Funktion davon (wie auch Luckie schon vorschlug), keine Prozedur. Übergebe deinen String text und baue in der Funktion den Rückgabewert result auf. Wenn du in der Funktion nicht text selber veränderst, dann entfällt schon mal 4.) ganz automatisch.

Aufrufen würdest du die Funktion mittext := verschluessel(text);

Überlege mal, wie die Funktion ausehen müsste. :)


goog - Mi 12.01.05 22:57

Hi
Vielen Dank für die guten Tips!!! :D

Aber funktioniert immer noch nicht, finde nicht den Fehler.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function verschluessel (text:string):string;
var i,l: integer;
  text2:string;
begin
l:=length(text);
if (l mod 2) <> 0 then text2[l]:='X';
for i:=1 to l do
 begin
  if text[i]=text[i+1then text2[i+1]:='X' else
  text2[i]:=text[i];
 end;
result:=text2;
end;


gruß johannes

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.


JayEff - Mi 12.01.05 23:14

erstmal aus den Codetags Delphitags machen, bitte...
zweitens: bist du auf die antwort von IngoD7 ÜBERHAUPT eingegangen? du überprüfst IMMERNOCH ob der letzte buchstabe mit dem letzten + 1 übereinstimmt (es GIBT keinen buchstaben hinter dem letzten!!!!!!) ausserdem müsstest du erstmal bestimmen, dass text2 die selbe länge hat wie text. das tust du nicht, du graifst auf buchstaben zu, die es nicht gibt; soweit ich weis ist ein String mit index (also ein Char dieses strings) eine nur-lesen eigenschaft, also kannst du text2[i] nichts zuweisen. versuchs mit text2:=text2+text[i]...
und als allerletztes: bitte schreib doch glecih von vornerein die Compilerfehlermeldungen dazu oder was an der sache nicht klappt. sonst müssen arme leute wieder ihre Glaskugeln rauskramen und anschmeissen... und arme mods müssen sich wieder um deine Code Tags kümmern.. (TUFKAPL.... *hrhr*)


BJ - Mi 12.01.05 23:24

Hi,

ich hab mir das ganze mal angesehen und aus meiner Sicht sollte es so funktionieren:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
function verschluessel (text:string):string;  
var i,l: integer;
  text2:string;
begin
l:=length(text);
text2:=text;                                   //text2 einen Wert zuteilen
if (l mod 2) <> 0 then text2:=text2+'X';       //Bei ungerade ein X anhängen
for i:=1 to l-1 do                             // bis zum vorletzten Element, da ich i+1 auslese
 begin
  if text2[i]=text2[i+1then insert('X',text2,i+1//Insert fügt das x an richtiger Stelle ein 
 end;
result:=text2;
end;


Mir ist aufgefallen, daß text2 am Anfang noch leerer String war --> daher Exception beim Start

Im Endeffekt kann man das ganze auch so gestalten:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
function verschluessel (text:string):string;  
var i,l: integer;
begin
l:=length(text);
if (l mod 2) <> 0 then text:=text+'X';
for i:=1 to l-1 do
 begin
  if text[i]=text[i+1then insert('X',text,i+1)
 end;
result:=text;
end;


Moderiert von user profile iconUGrohne: Code- durch Delphi-Tags ersetzt.


JayEff - Mi 12.01.05 23:26

JayEff hat folgendes geschrieben:
erstmal aus den Codetags Delphitags machen, bitte...

OH BITTEEEE!!! Jetzt hat sich TUFKAPL schon um die oben gekümmert... xD


BJ - Mi 12.01.05 23:34

Ach ja, ehe ichs vergesse.

Bei Zuweisungen wie: text:=fkt(text), wobei fkt eine Funktion mit Wertparameter ist braucht man keine Hilfsvariable einführen. Man kann die übergebenen Werte verwenden (lokale Parameter), da für diese eine lokale Kopie auf dem Stack angelegt wird.

Das wollte ich nur noch mal zeigen.


IngoD7 - Do 13.01.05 11:01

JayEff hat folgendes geschrieben:
soweit ich weis ist ein String mit index (also ein Char dieses strings) eine nur-lesen eigenschaft, also kannst du text2[i] nichts zuweisen.


Man kann natürlich String[x] direkt etwas zuweisen, nämlich ein Char. Ein String ist im Prinzip ein Array of Char. String[x] ist ein Element dieses Arrays.
String1[x] := String2[y] ist völlig korrekt.


IngoD7 - Do 13.01.05 11:12

BJ hat folgendes geschrieben:
Hi,
ich hab mir das ganze mal angesehen und aus meiner Sicht sollte es so funktionieren:
[...]
Im Endeffekt kann man das ganze auch so gestalten:
[...]


Leider nein! Du hast auch das 4.) aus meinem ersten Posting erwischt.
Das Wort "Gruppenbett" z.B. wird nicht korrekt behandelt.

Andererseits bewahrt dich dieser Fehler vor einer größeren Katastrophe, wie dem endlosen Einfügen von 'X' in das Wörtchen "LEXXER", z.B. 8)

Allgemein:
Wenn das hier ...
goog hat folgendes geschrieben:
Beispiel:
MITTWOCH --> MITXTWOCHX
... der Fall sein soll, dann dürfen eure ganzen Lösungen nicht das Wort am Anfang auf ungerade Länge prüfen, sondern nach der Verschlüsselung.

Apropos "ungerade": Dafür gibt es die Funktion Odd(). :wink:


MitschL - Do 13.01.05 11:49

Klingt nach einer Arbeit an http://www.delphi-forum.de/topic_PlayfairChiffre_34721.html

Moin,

wenn Du gerade an den Elementen rumsägst, warum schneidest Du nicht noch alle Satz- und Leerzeichen ab und baust danach (oder sogar gleich) eine Liste, die die neuen Zeichenpaare enthält?

by the way: Ich würde mit einer while-Schleife arbeiten, weil ich so Einfluß auf den Index habe.

gegrüßt!
MitschL


IngoD7 - Do 13.01.05 12:04

MitschL hat folgendes geschrieben:
Klingt nach einer Arbeit an http://www.delphi-forum.de/topic_PlayfairChiffre_34721.html

Ach, guck an ... :shock: Wird also noch was größeres. :)

MitschL hat folgendes geschrieben:
wenn Du gerade an den Elementen rumsägst, warum schneidest Du nicht noch alle Satz- und Leerzeichen ab und baust danach (oder sogar gleich) eine Liste, die die neuen Zeichenpaare enthält?

Mal langsam. Er tastet sich doch langsam ran. Das finde ich gut. Probleme gibt das bestimmt noch genug. :wink:

MitschL hat folgendes geschrieben:
Ich würde mit einer while-Schleife arbeiten, weil ich so Einfluß auf den Index habe.


So ist es. Und da hier schon falsche Lösungen gepostet wurden und goog das mit dem Index möglicherweise noch nicht ganz versteht, hier jetzt mal mein Lösungsvorschlag (etwas überkommentiert :P , zum Verständnis):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function verschluessel(text:string):string;    
var
  i : integer;
begin
i:=1;                       //i auf erstes Zeichen.
while i < length(text) do   //Solange i das Ende von text ..
                            //.. nicht erreicht hat, ..
   begin                       //.. schauen, ob der nächste Buchstabe ..
   if text[i]=text[i+1then   //.. identisch ist.
      begin                       //Wenn ja, 'X' einfügen und i ..
      insert('X',text,i+1);       //.. erhöhen, damit das eingefügte X ..
      inc(i);                     //.. nicht auch noch in die Prüfung ..
      end;                        //.. einbezogen wird.
   inc(i);                     //i auf nächstes Zeichen setzen
   end;
if odd(length(text)) then   //Wenn text-Länge ungerade, 'X' anhängen.
   text:=text+'X';
result:=text;               //Rückgabewert
end;


MitschL - Do 13.01.05 12:58

Etwa so,

es ist aber Vorsicht geboten. Wer weis, ob goog später in dieser Schleife auch die Satzzeichen rausschmeißen will.

gegrüßt!
MitschL


IngoD7 - Do 13.01.05 13:34

MitschL hat folgendes geschrieben:
es ist aber Vorsicht geboten. Wer weis, ob goog später in dieser Schleife auch die Satzzeichen rausschmeißen will.

Wie schon gesagt, das wird insgesamt spannend. Die Funktion, so wie sie da jetzt steht, ist zwar gemäß den hier geschilderten Anforderungen, aber sie ist trotzdem Schrott.

Irgendwas stimmt mit den Anforderungen nicht. Die Funktion ist so jedenfalls nicht eindeutig. Die Wörter "ROTHEXE" und "ROTHEE" bringen nach der Verschlüsselung dasselbe Ergebnis. Da wird der Rückweg schwer. :roll:


goog - Do 13.01.05 14:05

hi ingod7

Danke für die schnelle Hilfe :)
Aber du hast recht, das ware ist das noch nicht.
Wenn ich z.B ICHKOMMEAMMITTWOCH eingebe, dann gibt er
mir IC HK OM XM EA MX MI TX TW OC HX zurück.
Es müsste aber eigentlich IC HK OM ME AM MI TX TW OC HX rauskommen.
Es wird nämlich in Zweiergruppen untersucht und dann verschlüsselt.
Mit dem Schlüssel:"Mathematiker" kommt als Chiffre RD KM TG EG FH ED SZ QZ SR KW
heraus.
Man ich find das echt kompliziert!

vielleicht könnt ihr mir noch mal helfen?

gruß jo


IngoD7 - Do 13.01.05 14:56

goog hat folgendes geschrieben:

Es wird nämlich in Zweiergruppen untersucht und dann verschlüsselt.
Du Witzeimer! :eyecrazy:
Dann solltest du sowas zukünftig rechtzeitig schreiben ... :motz:

:wink:

Dann nimm das:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
function verschluessel (text:string):string;    
var
  i : integer;
begin
i:=1;                       //i initialisieren.
while i < length(text) do   //Solange i das Ende von text ..
                            //.. nicht erreicht hat, ..
   begin                       //.. schauen ob der nächste Buchstabe ..
   if text[i]=text[i+1then   //.. identisch ist.
      begin                       //Wenn ja, 'X' einfügen und i ..
      insert('X',text,i+1);       //.. erhöhen, damit das eingefügte X ..
      inc(i);                     //.. nicht auch in die Prüfung ..
      end;                        //.. einbezogen wird.
   inc(i,2);                     //i erhöhen --> auf nächste Zweiergruppe setzen
   end;
if odd(length(text)) then   //Wenn text-Länge ungerade, 'X' anhängen.
   text:=text+'X';
result:=text;               //Rückgabewert
end;


Aber bei "ROTHEXE" und "ROTHEE" kommt immer noch dasselbe raus. Also wieder nicht eindeutig.

Außerdem ergibt sich folgende Frage:
Was macht er, wenn in einer Zweiergruppe Gleichheit festgestellt wird, der zweite Buchstabe dieser Gruppe dann ein X wird und der ehemals zweite Buchstabe dann zum ersten Zwilling der nächsten Gruppe wird? Ein Zwilling in der nächsten Gruppe also, den es ohne das eingefügte X in der Gruppe davor gar nicht gegeben hätte.

Zu kompliziert ...? :nut: :lol:

Kurz: Was müsste bei "ERHATSEINENTEEENDLICH" herauskommen?


MitschL - Do 13.01.05 15:00

Der gesamte Payrfair-Algorithmus ist nicht wirklich reversibel - schon allein wegen der Doppelfeldbelegung i/j und der Nutzung des X als Füllzeichen oder dem Weglassen der Spaces.

Ich hab mir einen PayrFair+ gedacht, welcher mit normalen Sätzen arbeitet und statt einer 2-Dim-Matrix eine 4-Dim-Matrix nutzt. Füllzeichen ist ein #, welches dann nicht genutzt werden darf, wobei ich mir nicht sicher bin, ob das nachteilig ist, oder irrelevant. :?

gegrüßt!
MitschL

[edit]@IngoD7: Du hast ein E in der Abschlußfrage vergessen. :P


IngoD7 - Do 13.01.05 15:19

MitschL hat folgendes geschrieben:

[edit]@IngoD7: Du hast ein E in der Abschlußfrage vergessen. :P

:?:
Nö.
"ER HAT SEINEN TEE ENDLICH"
Die beiden e von "TEE" werden als gleiches Paar erkannt. Dadurch rutscht das zweite e in die nächste Gruppe und bildet mit dem e von "ENDLICH" wieder ein Zwillingspaar. Die Frage ist, ob der Code das erkennen muss oder nicht?

Das, was ich zuletzt gepostet hatte, erkennt das nicht. Ist das in Ordnung?


MitschL - Do 13.01.05 15:55

Das ist ein Beispiel dafür, daß ich nicht lesen kann, weil ich was ganz anderes las:

ERHATSEINENTEEENDLICH
er hat seinE ente endlich :shock: :rofl:

Wenn man Fehler finden will, kann man sie auch finden, wenn man Fehler hinzufügt.
(was'n Signature)

gegrüßt!
MitschL

[edit] Laut Payrfair-Algorithmus ist das leider nicht iO.


IngoD7 - Do 13.01.05 16:12

MitschL hat folgendes geschrieben:

er hat seinE ente endlich :shock: :rofl:

Hast früher zu oft und zu lange in der Badewanne gesessen, wie? :mrgreen:


MitschL - Do 13.01.05 16:22

Jaaaa,

damals war ich... aber ich schweife ab.

Ich würde den Chiffrier-Algorithmus so halt nicht wählen, wo wir doch mittlerweile mit verschränkten Elementarteilchen arbeiten können, was ja eine ziemlich tolle Codierung ist, ein wenig passende Hardware vorausgesetzt. 8)

gerüßt!
MitschL


Tino - Do 13.01.05 16:27

@goog: Könntest du bitte den Titel dieses Topics ändern. Mit Parameterübergabe hat dieses Topic ja leider seit x Beiträgen nichts mehr zu tun. In Zukunft bitte nicht vom Thema abkommen und lieber dafür ein neues Topic eröffnen.


goog - Do 13.01.05 16:42

Hi Leute!

MitschL hat geschrieben:
Ich würde den Chiffrier-Algorithmus so halt nicht wählen...

Ich hätte mich wahrscheinlich auch für ein anderes Verfahren entschieden, aber mit meinem Infolehrer ist nicht zu reden :? :evil:
Jetzt muss ich sehen wie ich damit zu recht komme.

gruß johannes


MitschL - Do 13.01.05 17:15

Hm,

dann sag deinem Lehrer einen schönen Gruß von mir (das wird ihn freuen 8) ): Er mag doch bitte etwas lehren, das sinnvoll ist. Ein Chiffrier-Algorithmus, der im strengen Sinne nichts taugt, weil das Dechiffrieren Auslegungssache ist, (- wegen Spaces und i/j -) ist bedingt sinnvoll, selbst wenn es gar nicht um den Algorithmus geht, sondern um die Programmierarbeit. :!:

Was jetzt noch toll wäre, ist ein Programm, welches genau den Fall errechnet, bei dem der Payrfair-Algorithmus versagt. :)

gegrüßt!


goog - Do 13.01.05 22:04

Hi MitschL!

Mein Lehrer meinte zum dechiffrieren sollte ich die gleiche Funktion benutzen wie zum chiffrieren.

HÄÄÄÄÄÄÄ:?:


MitschL - Fr 14.01.05 10:37

goog hat folgendes geschrieben:
Mein Lehrer meinte zum dechiffrieren sollte ich die gleiche Funktion benutzen wie zum chiffrieren.


Moin,

Das ist bei dem PayrFair eigentlich ganz einfach.
Du must dich nur fragen: was unterscheidet den verschlüsselten Text vom Original?
Satzzeichen sind nicht mehr vorhanden: Wenn ich auf die Werke vieler Chatter und Foren-Nutzer schaue, dann ist der Einsatz von Satzzeichen nicht uneingeschränkt empfehlbar. :)
Kein J: Reicht auch nicht.
Leerzeichen an jeder dritten Stelle: Das könnte klappen, wobei ich aber an anderer Stelle gesehen habe, daß deren Ergebnis ein einzelnes Wort darstellt. (Ich habe bisher drei verschiedene Varianten des Playfair gesehen, weshalb ich glaube, das das Original viel abstrakter gehalten war.)
Da diese Fragen nicht eindeutig beantwortet werden können, brauche ich eine definitive Angabe, wie ein kodierter und ein originaler Text aussehen soll.
Dann kannst du einen Aufruf machen, wie:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function PlayFair( text, key: String ): String;
var isChiffred: Boolean;
begin
  // hier kommt das rein, was noch unklar ist
  isChiffred := CheckText( text );
  
  if isChiffred then
    Result := Dechiffre( text, key )
  else
    Result := Chiffre( text, key );

end;

Intern arbeitest du weiterhin mit deinen einzelnen Methoden.

gegrüßt!
MitschL


IngoD7 - Fr 14.01.05 12:12

Bisher habe ich nichts zu Playfair gelesen, außer das, was in diesem Thread steht. Hatte den Vorteil, ich konnte ohne jede Wissensvorbelastung an die eigentlichen Delphi-Probleme von goog herangehen. Die scheinen aber nicht mehr im Fokus zu stehen ...

Also habe ich nun mal den anderen Thread ...
http://www.delphi-forum.de/topic_PlayfairChiffre_34721.html
... gelesen.

Und nun sollten wir vielleicht mal sortieren:

Was ich bisher nicht wusste ist, dass der Code, den wir hier im Thread behandelt haben, nicht Teil der Verschlüsselung ist. Es ist die Zerlegung (unter Einbringung der X und so weiter und so blubb). Die Zerlegung ist definitiv nicht reversibel, wie wir hier auch schon festgestellt haben. Nach der Decodierung eines nach Playfair codierten Textes muss man also hoffen, dass der "Text" (mit seinen ganzen X darin und ohne Zeichen und Leerstellen) irgendwie einen Sinn ergibt. Perfekt "zurückzerlegen" geht jedenfalls nicht.

Die Ver- und Entschlüsselungsroutinen können definitv nicht dieselben sein! Steht auch so in der Beschreibung im anderen Thread.

Die Routine (für die, wie wir nun wissen, Zerlegung), die ich zuletzt postete zerlegt nicht richtig. Diese hier nun sollte das aber tun (sie heißt jetzt folgerichtig "zerlege"):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function zerlege (text:string):string;    
var
  i : integer;
begin
i:=1;                       //i initialisieren.
while i < length(text) do   //Solange i das Ende von text ..
                            //.. nicht erreicht hat, ..
   begin                       //.. schauen ob der nächste Buchstabe ..
   if text[i]=text[i+1then   //.. identisch ist.
      begin                        //Wenn ja, 'X' einfügen. 
      insert('X',text,i+1);      
      end;                      
   inc(i,2);                   //i erhöhen --> auf nächste ..
   end;                        //.. Zweiergruppe setzen.
if odd(length(text)) then   //Wenn text-Länge ungerade, 'X' anhängen.
   text:=text+'X';
result:=text;               //Rückgabewert
end;


So, und wie machen wir hier im Thread nun weiter?


MitschL - Fr 14.01.05 12:28

Tja,

wir erstellen goog einen reversiblen PayrFair-Algorithmus mit ein paar interessanten Einfügungen, wie einer 4-dimensionalen Matrix, die 81 Zeichen aufnimmt und ein Füllzeichen nutzt, welches nicht im eigentlichen Text auftauchen tut. (wie oben erwähnt)
Wie soll er da noch sagen können, das das falsch ist, wenn er es nicht versteht?

Ich habe in der Schule und bei der Lehre gern Programme gebastelt, die trotz korrekter Logik und fast schon zu einfach gehaltener Syntax vom Lehrkörper unverstanden blieben. Ein wenig Mathematik einstreuen oder die Abstraktions-Ebene anheben und dann hört es bei erschreckend vielen Lehrern (- also alle, die ich kenne - ) auf. :?


gegrüßt!
MitschL

PS.: Ich weis; man kann auch über das Ziel hinausschießen, aber mich interessiert mein Gedanke - is ja auch mein Gedanke - und deswegen werde ich ihn so oder so umsetzen wollen. 8)


goog - Fr 14.01.05 19:21

Hi Leute !

Man find ich echt korrekt von euch das ihr mir so helft.
Jetzt muss ich bloß noch den restlichen Quelltext hinkriegen (hhhmmmmm....?)
Was die Lehrer betrifft da muss ich dir Recht geben.
Stellt man im Unterricht eine Frage, die nur einen kleinen Schritt weiter geht als der "normale" Schulstoff, bekommt man meist als Antwort: "Das kommt erst in höheren Klassenstufen dran" oder "Lass uns erst mal das jetzige Thema richtig behandeln". :evil: :?

gruß johannes


IngoD7 - Fr 14.01.05 19:49

goog hat folgendes geschrieben:
Schritt weiter geht als der "normale" Schulstoff, bekommt man meist als Antwort: "Das kommt erst in höheren Klassenstufen dran" oder "Lass uns erst mal das jetzige Thema richtig behandeln". :evil: :?
Tja, nur hat dein Lehrer nicht ganz Unrecht, oder? Du kriegst ja nun mal die geforderte Aufgabe (sprich: "das jetzige Thema") noch lange nicht so ohne weiteres hin. Warum also das Leben verkomplizieren und einen schwereren Playfair-Algorithmus bauen, den du deinem Lehrer niemals erklären könntest ...? Sei am Ende froh, wenn du die gestellte Aufgabe bewältigst und das Ergebnis verstehst. Ich stimme da also eurer Diskussion nicht zu, doch gleich "was richtiges" zu machen.

Wenn dein Lehrer dieses wackelige Playfair-Etwas haben will, so mache ihm das.

Was uns zurück zum Thema bringt:
Die Zerlegung hast du nun. Was gedenkst du kommt als nächstes?


goog - Fr 14.01.05 21:29

Hi IngoD7 !

Also ich hab mir mal ein paar Gedanken gemacht.
Als nächstes müsste ich Zeile und Spalte von je zwei aufeinanderfolgenden Buchstaben rausfinden und dann schauen ob entweder die Zeilen gleich sind oder die Spalten oder ob keines von beiden zutrifft. Zeilen und Spalten bekomme ich mit Z=(P-1) DIV 5 bzw.
S=(P-1) MOD 5 heraus.
Ich schau einfach an welcher Position der Buchstabe in meiner Matrix steht und bekomme so P und damit Zeilen und Spalten.
So sieht mein Quelltext für die Matrix aus:


Delphi-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:
procedure TForm1.Button1Click(Sender: TObject);
var code,nc,text: string;
      l,i,p,p2      :integer;
begin
code:='MATHEMATIKER';
text:=edit2.text;
text:=zerlege(text);
l:=length(code);
nc:='';
for i:=1 to l do
 begin
  if code[i]='j' then code[i]:='i';
  p:=pos(code[i],nc);
  if p=0 then nc:= nc+code[i];
 end;

alpha:=nc;
for i:=1 to 26 do
  begin
   p2:=pos(al[i],alpha);
   if p2=0 then
   alpha:=alpha+al[i];
  end;
edit3.text:=text;
end;


Ist das bis hierher so umsetzbar?

gruß goog


IngoD7 - Fr 14.01.05 22:02

goog hat folgendes geschrieben:
So sieht mein Quelltext für die Matrix aus:


Delphi-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:
procedure TForm1.Button1Click(Sender: TObject);
var code,nc,text: string;
      l,i,p,p2      :integer;
begin
code:='MATHEMATIKER';
text:=edit2.text;
text:=zerlege(text);
l:=length(code);
nc:='';
for i:=1 to l do
 begin
  if code[i]='j' then code[i]:='i';
  p:=pos(code[i],nc);
  if p=0 then nc:= nc+code[i];
 end;

alpha:=nc;
for i:=1 to 26 do
  begin
   p2:=pos(al[i],alpha);
   if p2=0 then
   alpha:=alpha+al[i];
  end;
edit3.text:=text;
end;


Ist das bis hierher so umsetzbar?

Du solltest mal ein wenig kommentieren, deinen code.

Was ich sehe ist, das nc dein Codewort ohne doppelte Buchstaben darstellt. al ist ein String mit allen Buchstaben, oder wie sehe ich das? Bin doch kein Hellseher ... Allerdings musst du da dann auch i oder j entfernen, sonst hat deine Matrix 26 Zeichen.

Wenn ja, wird alpha deine Matrix. Sehe ich das richtig?


goog - Fr 14.01.05 22:28

Hi Ingo D7!

Sorry wegen den comments hab ich total vergessen.


Delphi-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:
procedure TForm1.Button1Click(Sender: TObject);
var schluessel,ns,text: string;
      l,i,p,p2      :integer;
begin
schluessel:='MATHEMATIKER';   //hier ist der Schlüssel der Matrix festgelegt
//text:=edit2.text;             //der zu codierende Text wird eigelesen
//text:=zerlege(text);          //Funktionsaufruf(zerlege)
l:=length(schluessel);              
ns:='';                      //neuer schluessel ist leer
for i:=1 to l do             //für i:=1 bis Länge von schluessel tue    
 begin
  if schluessel[i]='j' then schluessel[i]:='i';   //aus j wird ein i
  p:=pos(schluessel[i],ns);                         //Position wird ermittelt
  if p=0 then ns:= ns+schluessel[i];   //wenn Buchstabe noch nicht vorhanden, dann dazu
 end;

matrix:=ns;             //matrix wird neuer Schluessel
for i:=1 to 25 do       //für i:=1 bis 25(anzahl der Buchstaben im Alphabet) tue
  begin
   p2:=pos(al[i],matrix);  //Position bestimmen
   if p2=0 then            // wenn Buchstabe noch nicht vorhanden, dann dazufügen
   matrix:=matrix+al[i];    
  end;
        
end;


Du hast Recht al ist eine Konstante mit allen Buchstaben außer j.
Ich habe alpha mal in matrix umgewandelt und code in schluessel, ich finde das verständlicher.
Ich habe matrix als globale Variable gewählt, ist das richtig?

gruß goog


IngoD7 - Fr 14.01.05 22:56

goog hat folgendes geschrieben:
Du hast Recht al ist eine Konstante mit allen Buchstaben außer j.

Wenn al alle Buchstaben außer j sind, warum geht die Schleife dann von 1 bis 26 ? :wink:

goog hat folgendes geschrieben:
Ich habe matrix als globale Variable gewählt, ist das richtig?

Kommt immer auf die sonstige Struktur eines Programmes an. Findest garantiert viele Leute, die globale Variablen grundsätzlich ablehnen. Mir ist's wurscht. Ich arbeite auch damit.

Aber was anderes:
Man kann mit matrix als String sicher leben. Du musst dann, wie du richtig gesehen hast, mit DIV und MOD und sowas arbeiten. Das geht natürlich, artet aber in viel Rechnerei aus, da du später ja auch noch rechts und links und oben und unten von P Buchstaben zum Ver- und Entschlüsseln suchen musst.

Bist du sicher, dass du keine echte Matrix, also ein array[1..5, 1..5] of char nehmen willst?


goog - Fr 14.01.05 23:13

Hi IngoD7!

Stimmt meine Schleife muss nur bis 25 gehen, man kann halt nicht an alles denken, oder?!
Vielleicht ist das besser mit deinem Vorschlag.
Nur leider sagt das mir nicht allzu viel mit array[1..5, 1..5] of char?
Wie würde sich denn dann mein Quelltext ändern?

gruß goog


IngoD7 - Sa 15.01.05 12:37

[NACHTRAG] (eine Stunde später):
Habe nochmal nachgedacht. Bleibe bei deinem Lösungsansatz! Es ist so möglich und du hast bereits durchblicken lassen, dass du mit einem String als Matrix wirst umgehen können. Kein Grund also, die Strategie zu wechseln.

Das hiernach stehende Ursprungsposting ist zwar grundsätzlich nicht falsch - deshalb lasse ich es auch stehen und lösche es nicht -, aber bleibe ruhig bei dem, wozu du dich mal entschieden hast. Das wird gut funktionieren.
[/Nachtrag]

goog hat folgendes geschrieben:
Vielleicht ist das besser mit deinem Vorschlag.
Nur leider sagt das mir nicht allzu viel mit array[1..5, 1..5] of char?
Wie würde sich denn dann mein Quelltext ändern?

Hm, habt ihr noch keine Arrays durchgenommen? Und dann solche Sachen programmieren müssen? Ich verstehe das nicht. Zu meiner Zeit gab's sowas nicht ....
Andererseits hat ein Matrix-String später beim Auffinden eines gesuchten Buchstabens den Vorteil, das einfach mit dem Befehl Pos machen zu können.

Ich weiß jetzt nicht, ob ich dir dazu raten soll. Normalerweise ist's wohl besser, du verfolgst das weiter, was du dir selber ausgedacht hast.

Trotzdem kurz zum Quelltext mit Arrays: Nun ja, du könntest zum Beispiel eine Matrix Matrixfeld als array[1..5,1..5] of char deklarieren. Damit hast du eine 5 x 5 große Matrix und kannst jedes einzelnes Feld darin direkt ansprechen; das Feld in Zeile 4, Spalte 2 z.B. mit Matrixfeld[4,2].
Erstellen (und später auch durchsuchen) würde man die Matrix mit zwei verschachtelten for-Schleifen.

Delphi-Quelltext
1:
2:
3:
4:
5:
for Zeile := 1 to 5 do
   for Spalte := 1 to 5 do
      begin
      ... 
      end;

Hat den Vorteil, dass wenn du hier einen Buchstaben innerhalb der Schleifen suchst und findest hast du sofort die Position in der Matrix (angezeigt durch Zeile und Spalte), ohne lange zu rechnen. Den Buchstaben unter einem gefundenen (für die Verschlüsselung) hast du dann einfach mit Matrixfeld[Zeile,Spalte+1] (man würde hier natürlich noch, wie sonst auch, den Überlauf über 5 beachten müssen).

Soll ein kleiner Ausritt gewesen sein. Du musst nun wissen, ob du dir über die Online-Hilfe oder über die Forum-Suche hier noch mehr Infos über Arrays anlesen musst, oder ob du das beiseite schiebst. Es gibt viele Methoden, die Matrix zu erstellen und später mit ihr zu arbeiten. Alle haben Vor- und Nachteile.

Es ist deine Entscheidung. Ich wollte dich nicht unnötig durcheinanderbringen, konnte aber auch nicht ahnen, dass dir Arrays kein Begriff sind.


goog - So 16.01.05 17:40

Hi IngoD7

Ich komm einfach nicht weiter.
Was soll ich jetzt alles in die Verschluessel Funktion mit reinpacken?
Sollte ich erst alle Zeilen und Spalten rausfinden und dann Verschluesseln oder gleich Buchstabe für Buchstabe?

gruß goog


IngoD7 - So 16.01.05 18:55

goog hat folgendes geschrieben:

Sollte ich erst alle Zeilen und Spalten rausfinden und dann Verschluesseln oder gleich Buchstabe für Buchstabe?

Buchstabe für Buchstabe wird ja nicht gehen. Du musst doch die Positionen eines Buchstabenpäärchens in der Matrix bestimmen, um überhaupt zu entscheiden, auf welche Art und Weise die Buchstaben dieses Päärchens verschlüsselt werden müssen.

Behandele deinen zu verschlüsselnden Text also päärchenweise. Dazu würde ich eine Schleife nehmen. Diese Schleife wird halb so viele Durchläufe brauchen, wie dein Text lang ist (eben, weil immer 2 Buchstaben zusammen abgearbeitet werden).

In der Schleife passiert folgendes:

a.) Du nimmst einen Buchstaben und schaust in der Matrix, welche Zeile und Spalte der hat.
b.) Dann nimmst du den nächsten Buchstaben und guckst wieder, welche Zeile und Spalte der hat.
c.) Dann musst du gucken, ob die beiden in derselben Spalte oder Zeile liegen und entsprechend (siehe Playfair-Beschreibung) die beiden Buchstaben verschlüsseln.
d.) Die verschlüsselten Buchstaben sammelst du jeweils in einem Ergebnisstring.

Das ist der theoretische Ansatz. Nun schaue mal, wie die Schleife auszusehen hat.


goog - So 16.01.05 20:08

Hi IngoD7 !

Ich hab mal versucht den Anfang hinzukriegen aber ich glaub das funktioniert nicht so richtig.
Ist das richtig mit den zwei for-Schleifen :?:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
function verschluessel (text:string):string ;
var i,j,p,l,p1,z1,s1,p2,z2,s2:integer;
begin
l:=length(text);
 for i:=1 to l do
  for j:=1 to 25 do
   if text[i]=matrix[j] then
     p1:=pos(text[i],matrix);
     z1:=(p1-1DIV 5;
     s1:=(p1-1MOD 5;
     inc(i);
    if text[i]=matrix[j] then
     p2:=pos(text[i],matrix);
     z2:=(p2-1DIV 5;
     s2:=(p2-1MOD 5;
     inc(i,2);
 If z1=z2 then ???


end;


Hoffentlich krieg ich das Programm bis Mittwoch fertig, sonst gibts wohl Ärger :evil: :cry:

gruß goog


IngoD7 - Mo 17.01.05 10:59

Da stimmt noch einiges nicht.
Wenn du deinen Code kommentieren würdest, würde dir dabei vielleicht einiges auffallen. Dann hättest du nämlich Schwierigkeiten, die zweite j-Schleife zu erklären. :wink:

Wir wollten eine Schleife machen und in der Schleife das hier:
IngoD7 hat folgendes geschrieben:
a.) Du nimmst einen Buchstaben und schaust in der Matrix, welche Zeile und Spalte der hat.
b.) Dann nimmst du den nächsten Buchstaben und guckst wieder, welche Zeile und Spalte der hat.
c.) Dann musst du gucken, ob die beiden in derselben Spalte oder Zeile liegen und entsprechend (siehe Playfair-Beschreibung) die beiden Buchstaben verschlüsseln.
d.) Die verschlüsselten Buchstaben sammelst du jeweils in einem Ergebnisstring.


Die Schleife hast du (deine i-Schleife). Mit der j-Schleife versuchst du, deine Matrix zu durchlaufen. Warum? Um die Position des Buchstabens zu finden? Das geht doch alleine mit Pos. Pos hast du doch beim Matrix erstellen z.B. schon sehr gut angewendet.

Die j-Schleife und deine beiden if text[i]=matrix[j] thensind also überflüssig.
((Nebenbei: Wenn im then-Teil mehrere Anweisungen ausgeführt werden sollen, müssen diese in begin..end eingeschlossen werden.))

Die i-Schleife ändern wir in eine while-Schleife, weil wir dann auch die Variable i innerhalb der Schleife verändern dürfen.

Das bringt mich zum nächsten Punkt. Du musst auch mal irgendwie versuchen, deine Sachen auszutesten. Das macht jeder mehr oder minder regelmäßig, weil niemand die Auswirkungen dessen, was er fabriziert, immer vorausschauen kann. Man testet nicht erst am Schluß das ganze Programm, sondern auch schon zwischendurch bestimmte Teile. Dabei wäre dir aufgefallen, dass du i nicht innerhalb der for-Schleife verändern darfst (Delphi meckert hier).

Aus deinem Code wird damit zunächst folgendes - achte auf die Kommentare darin:

Delphi-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:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
function Verschluessel(text:string):string;
var i,p,l,p1,z1,s1,p2,z2,s2:integer;
begin
l:=length(text);
i:=1;
 while i < l do
    begin
    if text[i]='J' then text[i]='I'//Ganz wichtig! J gibt es in der Matrix nicht.
    p1:=pos(text[i],matrix);         //Position des ersten Buchst. in p1.
    z1:=(p1-1DIV 5;                //FALSCH (ergibt keine Zeile von 1..5)
    s1:=(p1-1MOD 5;                //FALSCH (ergibt keine Spalte von 1..5)
    inc(i);                          //i auf nächsten Buchstaben
    
    if text[i]='J' then text[i]='I'//Ganz wichtig! J gibt es in der Matrix nicht.
    p2:=pos(text[i],matrix);         //Position des zweiten Buchst. in p2.
    z2:=(p2-1DIV 5;                //siehe oben beim ersten Buchstaben
    s2:=(p2-1MOD 5;
    inc(i);                          //i auf nächsten Buchstaben 
                                     
    if z1=z2 then //Wenn beide Buchst. in einer Zeile liegen, dann ..
       begin
       ...        //.. tue das mit z1, z2, s1 und s2, was du nach Playfair ..
       ...        //.. damit tun musst.
       end
    else
       if s1=s2 then //Oder aber wenn beide Buchst. in einer Spalte liegen, dann ..
          begin
          ...        //.. tue das mit z1, z2, s1 und s2, was du nach Playfair ..
          ...        //.. damit tun musst.
          end
       else          //Oder aber beide Buchstaben sind weder in der gleichen ..
          begin      //.. Zeile noch in der gleichen Spalte, dann ..
          ...        //.. tue das mit z1, z2, s1 und s2, was du nach Playfair ..
          ...        //.. damit tun musst.
          end;
    ...   //Hole mit den neuen z1, s1, z2 und s2 die Zeichen aus der Matrix ..
    ...   //.. und speichere sie in den Ergebnisstring.
    end;  //end while
end;


Denke an deine DIV- und MOD-Formeln. Probiere es aus. Nimm z.B. eine Extraformular, packe da ein Button1 und ein Memo1 rauf und mache dieses:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure TForm2.Button1Click(Sender: TObject);
var Position, Spalte, Zeile : integer;
begin
for Position := 1 to 25 do
    begin
    Zeile := (Position-1DIV 5;   //FALSCH
    Spalte := (Position-1MOD 5;  //FALSCH
    Memo1.Lines.Add('Position '+inttostr(Position)+' =  Zeile '+inttostr(Zeile)+'; Spalte '+inttostr(Spalte));
    end;
end;


Drücke da mal den Button. Anhand der angezeigten Ergebnisse im Memo wirst du schnell sehen, was da nicht stimmt.

Versuche mal, die Verschlüsselung fertig zu bekommen.


goog - Mo 17.01.05 18:05

Hi IngoD7!

Vielen Dank für die hilfe.

Ich glaub ich hab den Fehler.
Wie wäre es mit:

Delphi-Quelltext
1:
2:
 Zeile := ((Position-1DIV 5)+1;   
Spalte := ((Position-1MOD 5)+1;


Jetzt stimmt meine Rechnung

gruß goog


IngoD7 - Mo 17.01.05 19:42

goog hat folgendes geschrieben:
Hi IngoD7!

Vielen Dank für die hilfe.

Ich glaub ich hab den Fehler.
Wie wäre es mit:

Delphi-Quelltext
1:
2:
 Zeile := ((Position-1DIV 5)+1;   
Spalte := ((Position-1MOD 5)+1;


Jetzt stimmt meine Rechnung


Korrekt. :)

Und nun fix weiter mit der Verschlüsselungroutine. Es wir eng bis Mittwoch.


goog - Mo 17.01.05 19:56

Hi IngoD7!

Ich habs jetzt so gut wie fertig (glaub ich zumindest :lol: ).
Aber laufen wills noch nicht.
Warum zeigt er mir im edit4 nicht das ergebnis an, ich habe als ergebnisstring eine Variable "ergebnis" global deklariert in die die verschlüsselten Buchstaben geschrieben werden.
Hier ist jetzt mal mein bisheriger kompletter Quelltext:


Delphi-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:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
unit play;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    procedure Button1Click(Sender: TObject);


  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

const al='ABCDEFGHIKLMNOPQRSTUVWXYZ';
var matrix,ergebnis :string;

{$R *.DFM}


function zerlege (text:string):string;      
var  
  i : integer;  
begin  
i:=1;                       //i initialisieren.  
while i < length(text) do   //Solange i das Ende von text ..  
                            //.. nicht erreicht hat, ..  
   begin                       //.. schauen ob der nächste Buchstabe ..  
   if text[i]=text[i+1then   //.. identisch ist.  
      begin                        //Wenn ja, 'X' einfügen.   
      insert('X',text,i+1);        
      end;
   inc(i,2);                   //i erhöhen --> auf nächste ..
   end;                        //.. Zweiergruppe setzen.
if odd(length(text)) then   //Wenn text-Länge ungerade, 'X' anhängen.
   text:=text+'X';
result:=text;               //Rückgabewert
end;

function verschluessel (text:string):string ;
var i,p,l,p1,z1,s1,p2,z2,s2:integer;
begin
l:=length(text);
i:=1;
 while i < l do
    begin
    if text[i]='J' then text[i]:='I'//Ganz wichtig! J gibt es in der Matrix nicht.
    p1:=pos(text[i],matrix);         //Position des ersten Buchst. in p1.
    z1:=((p1-1DIV 5)+1;
    s1:=((p1-1MOD 5)+1;
    inc(i);                          //i auf nächsten Buchstaben

    if text[i]='J' then text[i]:='I'//Ganz wichtig! J gibt es in der Matrix nicht.
    p2:=pos(text[i],matrix);         //Position des zweiten Buchst. in p2.
    z2:=((p2-1DIV 5);
    s2:=((p2-1MOD 5);
    inc(i);                          //i auf nächsten Buchstaben

    if z1=z2 then //Wenn beide Buchst. in einer Zeile liegen, dann ..
       begin
        case p1 of
        5:   p1:=0;
        10:  p1:=5;
        15:  p1:=10;
        20:  p1:=15;
        25:  p1:=20;
        end;
        ergebnis[i-2]:=matrix[p1+1]; //ergebnis an der ersten stelle buchstaben zuweisen
        case p2 of
        5:   p2:=0;
        10:  p2:=5;
        15:  p2:=10;
        20:  p2:=15;
        25:  p2:=20;
        end;
        ergebnis[i-1]:=matrix[p2+1];    //ergebnis an der zweiten stelle buchstaben zuweisen
       end
    else
       if s1=s2 then //Oder aber wenn beide Buchst. in einer Spalte liegen, dann ..
          begin
           case p1 of
           21: p1:=-4;
           22: p1:=-3;
           23: p1:=-2;
           24: p1:=-1;
           25: p1:=0;
           end;
           ergebnis[i-2]:=matrix[p1+5];
           case p2 of
           21: p1:=-4;
           22: p1:=-3;
           23: p1:=-2;
           24: p1:=-1;
           25: p1:=0;
           end;
           ergebnis[i-1]:=matrix[p2+5];


          end
       else          //Oder aber beide Buchstaben sind weder in der gleichen ..
          begin      //.. Zeile noch in der gleichen Spalte, dann ..
           If s1<s2 then
            ergebnis[i-2]:=matrix[p1+(s2-s1)];
            ergebnis[i-1]:=matrix[p2-(s2-s1)];
           If s1>s2 then
            ergebnis[i-2]:=matrix[p1-(s1-s2)];
            ergebnis[i-1]:=matrix[p2+(s1-s2)];
          end;


    end;  //end while

end;


procedure TForm1.Button1Click(Sender: TObject);
var schluessel,ns: string;
      zeile,spalte,i,l,p,p2      :integer;
begin
schluessel:='MATHEMATIKER';   //hier ist der Schlüssel der Matrix festgelegt
text:=edit1.text;             //der zu codierende Text wird eigelesen
text:=zerlege(text);       //Funktionsaufruf(zerlege)
l:=length(schluessel);
ns:='';                   //neuer schluessel ist leer
for i:=1 to l do             //für i:=1 bis Länge von schluessel tue
 begin
  if schluessel[i]='j' then schluessel[i]:='i';   //aus j wird ein i
  p:=pos(schluessel[i],ns);                         //Position wird ermittelt
  if p=0 then ns:= ns+schluessel[i];   //wenn Buchstabe noch nicht vorhanden, dann dazu
 end;

matrix:=ns;             //matrix wird neuer Schluessel
for i:=1 to 25 do       //für i:=1 bis 25(anzahl der Buchstaben im Alphabet) tue
  begin
   p2:=pos(al[i],matrix);  //Position bestimmen
   if p2=0 then            // wenn Buchstabe noch nicht vorhanden, dann dazufügen
   matrix:=matrix+al[i];
  end;


edit2.text:=matrix;
edit3.text:=text;
edit4.text:=ergebnis;
end;


end.


Irgendwie krieg ich das mit der Rückgabe in der verschluessel Funktion net hin :?:

gruß goog


IngoD7 - Mo 17.01.05 21:15

Bin gerade etwas in Streß. Habe jetzt den ganzen Code nicht kontrolliert, nur überflogen.

Nur ein paar (wichtige) Dinge mal eben:

goog hat folgendes geschrieben:

Warum zeigt er mir im edit4 nicht das ergebnis an, [...]
Irgendwie krieg ich das mit der Rückgabe in der verschluessel Funktion net hin :?:


Möchtest du die Funktion Verschluessel nicht auch nochmal irgendwann in Button1Click aufrufen? :roll: :wink:

Deine DIV- und MOD-Formeln solltest du besser für beide Buchstaben korrekt haben.

Beim Erstellen der Matrix ersetzt du im Schlüssel "j" durch "i". Hier musst du große Buchstaben nehmen. Das ganze Programm setzt momentan voraus, dass nur große Buchstaben benutzt werden. Dann musst du auch Großbuchstaben ersetzen.

Auf was hast du eigentlich ergebnis zuvor gesetzt? Wenn du dabeigehst und einzelne Buchstaben von ergebnis veränderst, so sollte vorher auch was drinstehen. Normalerweise macht man das so, dass man ergebnis Stück für Stück aufbaut. Sinngemäß: ergebnis:=ergebnis+ErmittelterBuchstabe.

Als kosmetische Feinheit würde ich eine Funktion oder Prozedur MatrixErstellen machen, der du das Schlüsselwort übergibst (mache das, wenn du noch Zeit hast, später).

Und weiter geht's ....


goog - Mo 17.01.05 23:04

Hi IngoD7!

Juhhhhhuuuuuuuuuu :!: :D :D :D es läuft !!!

Vielen Dank
Ich hab noch mal ein paar Änderungen vorgenommen, auch mit der Funktion "matrix".

hier der neue Quelltext:


Delphi-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:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
unit play;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Edit3: TEdit;
    Edit4: TEdit;
    procedure Button1Click(Sender: TObject);


  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

const al='abcdefghiklmnopqrstuvwxyz';


{$R *.DFM}


function zerlege (text:string):string;      
var  
  i : integer;  
begin  
i:=1;                       //i initialisieren.  
while i < length(text) do   //Solange i das Ende von text ..  
                            //.. nicht erreicht hat, ..  
   begin                       //.. schauen ob der nächste Buchstabe ..  
   if text[i]=text[i+1then   //.. identisch ist.  
      begin                        //Wenn ja, 'X' einfügen.   
      insert('x',text,i+1);
      end;
   inc(i,2);                   //i erhöhen --> auf nächste ..
   end;                        //.. Zweiergruppe setzen.
if odd(length(text)) then   //Wenn text-Länge ungerade, 'X' anhängen.
   text:=text+'x';
result:=text;               //Rückgabewert
end;


function matrix(schluessel:string):string;
var ns: string;
    i,p,p2:integer;
begin
ns:='';                   //neuer schluessel ist leer
for i:=1 to length(schluessel) do             //für i:=1 bis Länge von schluessel tue
 begin
  if schluessel[i]='j' then schluessel[i]:='i';   //aus j wird ein i
  p:=pos(schluessel[i],ns);                         //Position wird ermittelt
  if p=0 then ns:= ns+schluessel[i];   //wenn Buchstabe noch nicht vorhanden, dann dazu
 end;

schluessel:=ns;             //schluessel wird neuer Schluessel
for i:=1 to 25 do       //für i:=1 bis 25(anzahl der Buchstaben im Alphabet) tue
  begin
   p2:=pos(al[i],schluessel);  //Position bestimmen
   if p2=0 then            // wenn Buchstabe noch nicht vorhanden, dann dazufügen
   schluessel:=schluessel+al[i];
  end;
result:=schluessel;
end;



function verschluessel (text,schluessel:string):string ;
var i,l,p1,z1,s1,p2,z2,s2:integer;
begin
l:=length(text);
i:=1;
 while i < l do
    begin
    if text[i]='j' then text[i]:='i'//Ganz wichtig! J gibt es in der Matrix nicht.
    p1:=pos(text[i],schluessel);         //Position des ersten Buchst. in p1.
    z1:=((p1-1DIV 5)+1;
    s1:=((p1-1MOD 5)+1;
    inc(i);                          //i auf nächsten Buchstaben

    if text[i]='j' then text[i]:='i'//Ganz wichtig! J gibt es in der Matrix nicht.
    p2:=pos(text[i],schluessel);         //Position des zweiten Buchst. in p2.
    z2:=((p2-1DIV 5)+1;
    s2:=((p2-1MOD 5)+1;
    inc(i);                          //i auf nächsten Buchstaben

    if z1=z2 then //Wenn beide Buchst. in einer Zeile liegen, dann ..
       begin
        case p1 of
        5:   p1:=0;
        10:  p1:=5;
        15:  p1:=10;
        20:  p1:=15;
        25:  p1:=20;
        end;
        text[i-2]:=schluessel[p1+1]; //ergebnis an der ersten stelle buchstaben zuweisen
        case p2 of
        5:   p2:=0;
        10:  p2:=5;
        15:  p2:=10;
        20:  p2:=15;
        25:  p2:=20;
        end;
        text[i-1]:=schluessel[p2+1]; //ergebnis an der zweiten stelle buchstaben zuweisen
       end
    else
       if s1=s2 then //Oder aber wenn beide Buchst. in einer Spalte liegen, dann ..
          begin
           case p1 of
           21: p1:=-4;
           22: p1:=-3;
           23: p1:=-2;
           24: p1:=-1;
           25: p1:=0;
           end;
           text[i-2]:=schluessel[p1+5];
           case p2 of
           21: p2:=-4;
           22: p2:=-3;
           23: p2:=-2;
           24: p2:=-1;
           25: p2:=0;
           end;
           text[i-1]:=schluessel[p2+5];


          end
       else          //Oder aber beide Buchstaben sind weder in der gleichen ..
          begin      //.. Zeile noch in der gleichen Spalte, dann ..
           If s1<s2 then
            text[i-2]:=schluessel[p1+(s2-s1)];
            text[i-1]:=schluessel[p2-(s2-s1)];
           If s1>s2 then
            text[i-2]:=schluessel[p1-(s1-s2)];
            text[i-1]:=schluessel[p2+(s1-s2)];
          end;
    end;  //end while
result:=text;
end;


procedure TForm1.Button1Click(Sender: TObject);
var schluessel,text: string;
begin
schluessel:='playfair';   //hier ist der Schlüssel der Matrix festgelegt
text:=edit1.text;             //der zu codierende Text wird eigelesen
text:=zerlege(text);          //Funktionsaufruf(zerlege)
edit3.text:=text;
schluessel:=matrix(schluessel);
edit2.text:=schluessel;
text:=verschluessel(text,schluessel);
edit4.text:=text;
end;


jetzt muss ich bloß noch das entschlüsseln hinkriegen.
Kann ich das nun auch mit der Funktion "verschluessel" machen?

gruß goog


IngoD7 - Mo 17.01.05 23:36

Zum Schluß bist du ein paar - sagen wir mal - "eigenwillige" Wege gegangen. :wink:
Nun gut, das ist deine "künstlerische Freiheit". Wichtig dürfte sein, dass am Ende das richtige herauskommt.

Da tut es aber bestimmt noch nicht. Und zwar folgendes:
Wenn du möchtest, dass die Anweisungen MacheA und MacheB ausgeführt werden, wenn BedingungX der Fall ist, dann müssen die beiden Anweisungen in begin..end eingeschlossen werden.
Also so (Pseudo):

Delphi-Quelltext
1:
2:
3:
4:
5:
if BedingungX then
   begin
   MacheA;   //Führt MacheA aus, wenn BedingungX der Fall ist.
   MacheB;   //Führt MacheB aus, wenn BedingungX der Fall ist.
   end;

Wenn du begin..end weglässt, passiert folgendes:

Delphi-Quelltext
1:
2:
3:
if BedingungX then
   MacheA;   //Führt MacheA aus, wenn BedingungX der Fall ist.
MacheB;   //Führt MacheB immer(!) aus.

Schau jetzt mal, wo du das missachtest hast und korrigiere es.

Zum Entschlüsseln sei gesagt, dass es ein Gerücht ist, zu behaupten, sie ginge in der selben Routine wie das Verschlüsseln. Überlege mal: Wo du vorher zum Verschlüsseln in der Matrix beispielsweise den Buchstaben unter dem gefundenen nehmen musstest (oder den rechts davon), so musst du zum Entschlüsseln den darüber (bzw. den links davon) nehmen. Das geht natürlich nicht in derselben Routine. Man könnte Teile der Routine verwenden, nämlich die Suche der Buchstaben in der Matrix. Aber ab deinen case-Anweisungen muss dann unterschieden werden: Ver- oder entschlüssele ich?

Wenn's nicht unbedingt anders gefordert ist, würde ich eine Extra-Funktion für das Verschlüsseln schreiben.

Wenn du nun in die Endphase gehst, dann teste dein Programm auf Herz und Nieren. Ich werde dir das nicht abnehmen. Ich weise dich auf mehr oder minder offensichtliche Fehler im Code - wenn ich sie entdecke - hin. Wenn aber uns beiden irgendetwas durch die Lappen geht, was jederzeit passieren kann, so wird das nur ein abschließender gründlicher Test ans Tageslicht bringen. Das bedeutet nix anderes, als dass du irgendwo Referenzverschlüsselungen auftreiben musst, um sie mit den Ergebnissen deines Programmes zu vergleichen. Das kann sehr gut auch bedeuten, dass du mal zwei oder drei Verschlüsselungen von Hand durchführen musst, um zu sehen, ob dein Programm auf dasselbe Ergebnis kommt. :wink:


goog - Di 18.01.05 00:01

Hi IngoD7!

Ich glaub so gehts mit dem entschlüsseln.
nur das beim entschlüsselten Text die eingefügten x noch stören.


Delphi-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:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
function entschluessel (text,schluessel:string):string;
var i,l,p1,z1,s1,p2,z2,s2:integer;
begin
l:=length(text);
i:=1;
 while i < l do
    begin
    //if text[i]='j' then text[i]:='i'; //Ganz wichtig! J gibt es in der Matrix nicht.
    p1:=pos(text[i],schluessel);         //Position des ersten Buchst. in p1.
    z1:=((p1-1DIV 5)+1;
    s1:=((p1-1MOD 5)+1;
    inc(i);                          //i auf nächsten Buchstaben

    if text[i]='j' then text[i]:='i'//Ganz wichtig! J gibt es in der Matrix nicht.
    p2:=pos(text[i],schluessel);         //Position des zweiten Buchst. in p2.
    z2:=((p2-1DIV 5)+1;
    s2:=((p2-1MOD 5)+1;
    inc(i);                          //i auf nächsten Buchstaben

    if z1=z2 then //Wenn beide Buchst. in einer Zeile liegen, dann ..
       begin
        case p1 of
        1:   p1:=6;
        6:   p1:=11;
        11:  p1:=16;
        16:  p1:=21;
        21:  p1:=26;
        end;
        text[i-2]:=schluessel[p1-1]; //ergebnis an der ersten stelle buchstaben zuweisen
        case p2 of
        1:   p2:=5;
        6:   p2:=10;
        11:  p2:=15;
        16:  p2:=20;
        21:  p2:=25;
        end;
        text[i-1]:=schluessel[p2-1]; //ergebnis an der zweiten stelle buchstaben zuweisen
       end
    else
       if s1=s2 then //Oder aber wenn beide Buchst. in einer Spalte liegen, dann ..
          begin
           case p1 of
           21: p1:=-4;
           22: p1:=-3;
           23: p1:=-2;
           24: p1:=-1;
           25: p1:=0;
           end;
           text[i-2]:=schluessel[p1-5];
           case p2 of
           21: p2:=-4;
           22: p2:=-3;
           23: p2:=-2;
           24: p2:=-1;
           25: p2:=0;
           end;
           text[i-1]:=schluessel[p2-5];


          end
       else          //Oder aber beide Buchstaben sind weder in der gleichen ..
          begin      //.. Zeile noch in der gleichen Spalte, dann ..
           If s1<s2 then
            begin
             text[i-2]:=schluessel[p1+(s2-s1)];
             text[i-1]:=schluessel[p2-(s2-s1)];
            end;
           If s1>s2 then
            begin
             text[i-2]:=schluessel[p1-(s1-s2)];
             text[i-1]:=schluessel[p2+(s1-s2)];
            end;
          end;
    end;  //end while
result:=text;
end;


gruß goog


IngoD7 - Di 18.01.05 03:58

goog hat folgendes geschrieben:
Hi IngoD7!

Ich glaub so gehts mit dem entschlüsseln.
nur das beim entschlüsselten Text die eingefügten x noch stören.


Okay, wie gesagt: Probiere es aus, dass du dir wirklich sicher sein kannst, alles richtig gemacht zu haben. Ich habe es nicht getestet.

Die X sind beim Zerlegen reingekommen und die bekommst du auch nicht wieder 100%-ig raus. Siehe im Verlauf dieses Threads. Da waren wir schon drauf eingegangen, dass es verschiedene Worte gibt, die nach dem Zerlegen dasselbe Ergebnis bringen. Kein Algorithmus der Welt wird hier dann jetzt 100%-ig erkennen können, welches Ursprungswort es mal gewesen ist.

Das Programm kann getrost nach dem Entschlüsseln aufhören. Zurückzerlegen geht nicht - jedenfalls nicht bei dem Zerlege-Algorithmus, wie wir ihn verstanden und du ihn jetzt programmiert hast. Ich denke mal, das hat Playfair auch nicht vorgesehen. Jedenfalls nicht ein Playfair mit einer schlappen 5x5-Matrix.


King of the Road - Mo 20.03.06 14:15
Titel: Playfair Verschlüsselung
Hallo Leute,

Ich habe ein Problem. Ich habe eine BVuchstaben Kombination, die nach Playfair verschlüsselt ist. Leider habe ich keine Ahnung, wie man diese Entschlüsselt.
Die Buchstaben Kombination lautet: O G N I I N U W.

Kann mir jemand weiterhelfen und diese Kombination entschlüsseln?

Wäre euch sehr dankbar!

Gruß
King of the Road


Tilman - Sa 25.03.06 15:27
Titel: Re: Playfair Verschlüsselung
@
user profile iconKing of the Road hat folgendes geschrieben:
Hallo Leute,

Ich habe ein Problem. Ich habe eine BVuchstaben Kombination, die nach Playfair verschlüsselt ist. Leider habe ich keine Ahnung, wie man diese Entschlüsselt.
Die Buchstaben Kombination lautet: O G N I I N U W.

Kann mir jemand weiterhelfen und diese Kombination entschlüsseln?


Ich glaube das ist definitiv zu kurz als das man es entschlüsseln könnte, jedenfalls wenn du nicht weitere Informationen (z.B. den PlayFair-Kasten) hast.

Ansonsten kann ich nur das Buch "Verschlüsselte Botschaften" empfehlen, da stehen viele Algorithmen, auch Playfair, drin und z.T. wie man sie entschlüsselt. Ausserdem ist glaub ich (hab meins grad nicht da) ein Verfahren angegeben welches das Doppelbuchstaben-Problem, welches im Anfang von diesem Thread beschrieben wurde, umgeht, Doppelkasten hieß das glaube ich.