Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Permutationschiffre


Fliegerbenny - Mi 03.12.08 14:21
Titel: Permutationschiffre
Hallöchen,


ich habe mal eine Frage. Ich habe in der Schule die Aufgabe bekommen ein Programm in Delphi zu schreiben, was einen beliebigen Klartext verschlüsselt und zwar mit der Permutation. Ausspucken soll das Programm den Schlüssel, sowie das Chiffrat.

Also mal ein Beispiel. Aus dem Klartext P = "Hallo" wird C = "aolHl"

wenn man allgemein betrachtet das C=k(P) ist dann ist k die Permutation. In meinem Beispiel wäre k= 2,5,3,1,4

Soweit so gut.. Ich denke, dass ich die Aufgabe lösen kann, aber ein paar Sachen verstehe ich leider nicht.

Ich habe also angefangen aus einem Edit den Inhalt auszulesen, die Länge zu ermitteln und das in ein dynamisches Array zu schreiben.

Nun stehe ich genau an diesem Punkt. Wie bekomme ich denn jedes einzelne Zeichen in das Array? Ziel soll sein, die Reihenfolge danach belibig zu vertauschen...

Hier mein bisheriger Quelltext


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
procedure TForm1.Button2Click(Sender: TObject);
var     eingabe:string;
        laenge:integer;
        dynpermut: array of integer;

begin
        eingabe := Edit1.Text;          //Eingabe
        laenge := length(eingabe);     //laenge beinhaltet die Länge des strings aus Edit1
        SetLength(dynpermut, laenge);  //Länge des Arrays mit var laenge
        dynpermut := copy(eingabe, laenge, 0);

end;


Wie ihr seht war meine Idee copy zu benutzen. Das geht leider nicht.


Ich hoffe, ihr könnt mir helfen. :)
Bin etwas raus aus Delphi und möchte mit dem Projekt nun auch wieder genauer einsteigen.


Gruß

Benny


jaenicke - Mi 03.12.08 14:28

Du kannst auf einzelne Buchstaben wie in einem Array zugreifen, also eingabe[i] ist der i-te Buchstabe. Mit Ord bekommst du den Asciiwert des Zeichens, zum Beispiel 65 für A oder 97 für a, falls du das brauchst (weil dein Array vom Typ Integer ist).
Mit einer for-Schleife kannst du die einzelnen Buchstaben durchgehen und übertragen.


Fliegerbenny - Mi 03.12.08 14:44

Danke für die schnelle Hilfe,

ich habe aus dem Array erst mal ein Char Array gemacht. Habe nun durch recherchieren rausgefunden, dass man mit copymemory weiterkommt.

Siehe da, das hat funktioniert. :)

Nun ist also der Klartext im Array...

Jetzt muss ich die Permutation erzeugen

Für Hallo als Klartext wäre die permutation ja (1,2,3,4,5) .. jetzt heißt es den Schlüssel zu erzeugen durch eine wilde Vertauschung der Zahlen...

Das sollte man eventuell mit einer for-Schleife realisieren?

Würde mich freuen, wenn ihr mir nochmal helfen könntet.

Danke erstmal schon an Sebastian



Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  
procedure TForm1.Button2Click(Sender: TObject);
var     eingabe:string;
        laenge:integer;
        dynpermut: array of char;

begin
        eingabe := Edit1.Text;          //Eingabe
        laenge := length(eingabe);     //laenge beinhaltet die Länge des strings aus Edit1
        SetLength(dynpermut, laenge);  //Länge des Arrays mit var laenge
        copymemory(@dynpermut,@eingabe,laenge);
end;


jaenicke - Mi 03.12.08 14:49

http://www.delphi-library.de/viewtopic.php?t=71713
Das ist ein Algorithmus zum Mischen.


Fliegerbenny - Mi 03.12.08 16:37

Hallo,

finde die Methode nach Fisher gut und nachvollziehbar...

Jedoch klappt das noch nicht ganz..wo liegt der fehler?



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:
procedure TForm1.Button2Click(Sender: TObject);
var     eingabe,ausgabe:string;
        laenge,i,j,t:integer;
        dynpermut: array of char;
        intpermut: array of integer;



begin
        eingabe := Edit1.Text;          //Eingabe
        laenge := length(eingabe);     //laenge beinhaltet die Länge des strings aus Edit1
        SetLength(dynpermut, laenge);  //Länge des Arrays mit var laenge
        copymemory(@dynpermut,@eingabe,laenge); //kopieren des Strings in das Array (dynpermut)
        SetLength(intpermut, laenge);
        copymemory(@intpermut,@dynpermut,laenge);
        for I := Low(intpermut) to High(intpermut) do begin
        J := I + Random(Length(intpermut) - I);
        T := intpermut[J];
        intpermut[J] := intpermut[I];
        intpermut[I] := T;
        end;
        copymemory(@dynpermut,@intpermut,laenge);
        copymemory(@ausgabe,@dynpermut,laenge);
        label6.Caption := ausgabe;


end;


Ich hoffe ihr könnt mir helfen...


Volle - Do 04.12.08 09:03

solltest du nicht erstmal interpermut mit zahlen von 1 bis Textlaenge fuellen? Diese dann mit dem algorithmus vertauschen und danach das dynpermut so anordnen wie die zahlen im interpermut drinstehen?


jaenicke - Do 04.12.08 10:57

Das Kopieren mit CopyMemory geht so auch nicht bzw. muss ja nicht doppelt gemacht werden.

Eine Möglichkeit ist diese (er hat schon eine ähnliche funktionierende Lösung, deshalb poste ich das für spätere Leser):

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:
procedure TForm1.Button1Click(Sender: TObject);

  // aus: http://www.delphi-library.de/viewtopic.php?t=71713
  procedure ShuffleFisherYates(var aArray: array of Integer);
  var
    i, j, tmp: Integer;
  begin
    // alle Elemente des Feldes durchlaufen
    for i := Low(aArray) to High(aArray) do begin
      // neue, zufällig Position bestimmen
      j := i +Random(Length(aArray) - i);
      // Element Nr. i mit Nr. j vertauschen (3ecks-Tausch)
      tmp := aArray[j];
      aArray[j] := aArray[i];
      aArray[i] := tmp;
    end;
  end;

  function GetKeyDisplay(Key: array of Integer): String;
  var
    i: Integer;
  begin
    Result := '';
    for i := 0 to high(Key) do
      Result := Result + ' ' + IntToStr(Key[i]);
  end;

var
  eingabe, ausgabe: string;
  laenge, i: integer;
  permut: array of integer;
begin
  // Eingabe prüfen und auslesen
  if Edit1.Text = '' then
  begin
    ShowMessage('Bitte den Klartext angeben');
    Exit;
  end;
  eingabe := Edit1.Text;
  laenge := Length(eingabe);

  // Schlüssel generieren und anzeigen
  SetLength(permut, laenge);
  for i := 0 to High(permut) do
    permut[i] := i + 1;
  ShuffleFisherYates(permut);
  Label4.Caption := 'Der Schlüssel lautet:' + GetKeyDisplay(permut);

  // Ausgabe erstellen
  SetLength(ausgabe, Length(eingabe));
  for i := 1 to Length(permut) do
    ausgabe[i] := eingabe[permut[i - 1]];
  ausgabe := 'Das Chiffrat lautet: ' + ausgabe;
  Label5.Caption := ausgabe;
end;