Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Verschlüsslungsprogramm?


newbie333 - Fr 03.07.09 16:37
Titel: Verschlüsslungsprogramm?
Hallo :)
Ich versuche ein kleines "Verschlüsslungsprogramm" zu programmieren. Bin aber immernoch neu auf dem Gebiet des Programmierens ;)
Wie kann ich das denn machen, wenn ich zum Beipiel dem Buchstaben A den Buchstaben B zuordnen will. B -> C, C-> D usw. wie sieht das in Delphi aus?
habs schon ausprobiert aber wurde nichts..
ich kanns ja mal zeigen..


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:
procedure TForm1.Button1Click(Sender: TObject);
var klartext,laenge,n,position:integer;
neu,buchstabe:string;
begin
klartext:=strtoint(edit1.text);
laenge:=length(edit1.text);
n:=laenge;
position:= length(inttostr(n));
neu:=' ';
while n <> 0 do
begin
if position = strtoint('a'then
buchstabe:='g';
neu:=neu+buchstabe;
if position = strtoint('b'then
buchstabe:='h';
neu:=neu+buchstabe;
if position = strtoint('c'then
buchstabe:='i';
neu:=neu+buchstabe;
if position = strtoint('d'then
buchstabe:='j';
neu:=neu+buchstabe;
if position = strtoint('e'then
buchstabe:='k';
neu:=neu+buchstabe;
if position = strtoint('f'then
buchstabe:='l';
neu:=neu+buchstabe;
if position = strtoint('g'then
buchstabe:='m';
neu:=neu+buchstabe;
if position = strtoint('h'then
buchstabe:='n';
neu:=neu+buchstabe;
if position = strtoint('i'then
buchstabe:='o';
neu:=neu+buchstabe;
if position = strtoint('j'then
buchstabe:='p';
neu:=neu+buchstabe;
if position = strtoint('k'then
buchstabe:='q';
neu:=neu+buchstabe;
if position = strtoint('l'then
buchstabe:='r';
neu:=neu+buchstabe;
if position = strtoint('m'then
buchstabe:='s';
neu:=neu+buchstabe;
if position = strtoint('n'then
buchstabe:='t';
neu:=neu+buchstabe;
if position = strtoint('o'then
buchstabe:='u';
neu:=neu+buchstabe;
if position = strtoint('p'then
buchstabe:='v';
neu:=neu+buchstabe;
if position = strtoint('q'then
buchstabe:='w';
neu:=neu+buchstabe;
if position = strtoint('r'then
buchstabe:='x';
neu:=neu+buchstabe;
if position = strtoint('s'then
buchstabe:='y';
neu:=neu+buchstabe;
if position = strtoint('t'then
buchstabe:='z';
neu:=neu+buchstabe;
if position = strtoint('u'then
buchstabe:='a';
neu:=neu+buchstabe;
if position = strtoint('v'then
buchstabe:='b';
neu:=neu+buchstabe;
if position = strtoint('w'then
buchstabe:='c';
neu:=neu+buchstabe;
if position = strtoint('x'then
buchstabe:='d';
neu:=neu+buchstabe;
 
dec(n);
end;
label1.caption:=neu;
 
end;
 
end.


Wäre nett, wenn jemand helfen könnte..
Danke schonmal.


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Fr 03.07.2009 um 16:56


Sinspin - Fr 03.07.09 18:14

Wie meinst du das denn, das es nichts wurde?
Das sich dein Quelltext nicht übersetzen lässt ist ja klar.
StrToInt wandelt einen String in dem eine oder mehrere Ziffern hintereinander stehen in dessen numerische Entsprechung um.
Um den ASCII Code eines Zeichens zu bekommen musst du Ord() verwenden, zurück zu einem Zeichen kommt du mit Char()Chr().
Wenn du das Zeichen als Zahl (ASCII Code) vorliegen hast kannst du abziehen oder addieren was du willst.

Also würde dein spass so aussehen (pseudocode)

Quelltext
1:
2:
3:
4:
5:
zieltext ist leer;
über laufvariable von 1 bis länge des klartextes
  aktuelles zeichen = zeichen von klartextes an der stelle der laufvariable;
  neues zeichen = als zeichen ( als ASCII Code ( aktuelles zeichen ) +1 );
  zieltext = zieltext und neues zeichen

// € : Char durch Chr ersetzt :oops:


ffgorcky - Fr 03.07.09 18:31

Also ich könnte mir jetzt gerade vorstellen, dass es doch eigentlich einfach so gehen müsste:

Delphi-Quelltext
1:
2:
3:
4:
for i:=0 to length(memoZuVerschluzesselnderText)-1 do
    begin
    memoZuVerschluesselnderText.Text[i]:=IntToStr(StrToInt(memoZuVerschluesselnderText.Text[i])+1);
    end;

Das müsste dann doch eigentlich genau Deinen erwünschten Effekt (A wird zu B, B zu C...) haben!
Ich habe jetzt hier aber leider gerade nicht direkt die Möglichkeit, es auszuprobieren...

Nur dadurch hast Du das Original danach dann nicht mehr - also müsstest Du das dann wohl besser doch mit einem zweiten Memo (oder RichEdit) machen.


jaenicke - Fr 03.07.09 18:34

user profile iconffgorcky hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
   memoZuVerschluzesselnderText[i]:=IntToStr(StrToInt(memoZuVerschluzesselnderText[i])+1);                    
Und was, wenn da gar keine Zahl steht in dem Buchstaben? :gruebel:
Zudem: memoZuVerschluzesselnderText.Text meinst du wohl? So ein zeichenweiser Zugriff auf .Text ist aber extrem langsam und wird beim Schreiben auch nicht klappen.

user profile iconSinspin hat ja Ord bereits genannt, das Gegenstück ist Chr. (Ohne a)


ffgorcky - Fr 03.07.09 18:43

Also ich meine doch, dass jedes Zeichen doch auch direkt in eine Zahl umwandelbar ist - oder bin ich da jetzt "auf dem Holzweg"?
PS: user profile iconjaenicke, ich habe jetzt auch gleich mal eben mein vorheriges Posting auf Deinen Hinweis hin verbessert.


Marc. - Fr 03.07.09 18:50

user profile iconffgorcky hat folgendes geschrieben Zum zitierten Posting springen:
Also ich meine doch, dass jedes Zeichen doch auch direkt in eine Zahl umwandelbar ist - oder bin ich da jetzt "auf dem Holzweg"?

Das ist aber nicht mit der Funktion StrToInt möglich, wie user profile iconjaenicke bereits geschrieben hat. Um an den ASCII-Code eines Zeichens zu gelangen, kannst du entweder die Funktion Ord() verwenden oder dieses mit Byte() casten. ;)


jaenicke - Fr 03.07.09 21:10

user profile iconffgorcky hat folgendes geschrieben Zum zitierten Posting springen:
PS: user profile iconjaenicke, ich habe jetzt auch gleich mal eben mein vorheriges Posting auf Deinen Hinweis hin verbessert.
Ich habe doch genau geschrieben, dass es so nicht geht. :mrgreen:

Probier es bitte einmal aus. ;-)


newbie333 - Fr 03.07.09 22:07

ok, ich versuch das morgen mal.
ich sag dann bescheid. Danke :)


newbie333 - Sa 04.07.09 09:21

Guten morgen.. :)

Wie genau setzt man die Zeile denn um?
neues zeichen = als zeichen ( als ASCII Code ( aktuelles zeichen ) +1);?

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TForm1.Button1Click(Sender: TObject);
var text,neuertext,n, laenge:integer;
begin
Edit1.clear;
Edit2.clear;
text:=strtoint(edit1.text);
for n:=0 to length(edit1.text)-1 do // hier stimmt bestimmt was nicht von den datentypen..?



end;

end.


weiter als so komm ich gerade nicht.. :(


jaenicke - Sa 04.07.09 10:25

user profile iconnewbie333 hat folgendes geschrieben Zum zitierten Posting springen:
Wie genau setzt man die Zeile denn um?
neues zeichen = als zeichen ( als ASCII Code ( aktuelles zeichen ) +1);?
:roll:
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconSinspin hat ja Ord bereits genannt, das Gegenstück ist Chr. (Ohne a)


Popov - Sa 04.07.09 11:17

user profile iconnewbie333 hat folgendes geschrieben Zum zitierten Posting springen:
Ich versuche ein kleines "Verschlüsslungsprogramm" zu programmieren.


Ich hab dein Code vom ersten Beitrag genommen und den etwas optimiert. Jeden Buchstaben einzeln mit if then abzufragen ist zu aufwendig. Das Ganze kannst du auch machen in dem du eine "Tabelle" abfragst und so die Buchstaben tauscht. Ob das eine gute Verschlüsselung ist, lasse ich mal weg, denn es geht nur um das Prinzip.

Es wid der Text aus dem Edit1 Textfeld verschlüsselt.

Zuerst die Verschlüsselungstabelle:

Delphi-Quelltext
1:
2:
3:
const
code = 'ghijklmnopqrstuvwxyzabcdef';
//     'abcdefghijklmnopqrstuvwxyz';

Verschlüsseln:

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:
procedure TForm1.Button1Click(Sender: TObject);
var
  s, s2: String;
  c, c2: Char;
  i, k: Integer;
begin
  s := Edit1.Text;

  for i := 1 to Length(s) do
  begin
    c := s[i];
    if (c >= 'a'and (c <= 'z'then
      begin
        k := Ord(c) - 96{a ist ASCII 97, also alles davor abziehen, damit a = 1 ist}
        c2 := code[k];  // Ersatzzeichen aus der Verschlüsselungstabelle nehmen
        s2 := s2 + c2; // hier nur a bis z
      end
    else
      s2 := s2 + c; // hier der Rest
  end;

  Edit1.Text := s2;
end;

Entschlüsseln:

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:
procedure TForm1.Button2Click(Sender: TObject);
var
  s, s2: String;
  c, c2: Char;
  i, k: Integer;
begin
  s := Edit1.Text;

  for i := 1 to Length(s) do
  begin
    c := s[i];
    if (c >= 'a'and (c <= 'z'then
      begin
        k := Pos(c, code) + 96;
        c2 := Chr(k);
        s2 := s2 + c2; // hier nur a bis z
      end
    else
      s2 := s2 + c; // hier der Rest
  end;

  Edit1.Text := s2;
end;


ffgorcky - Sa 04.07.09 12:28

Also ich habe jetzt mal folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
procedure TForm1.ButtonVerschluesselnClick(Sender: TObject);
var i:integer;
begin
LabelVerschluesselt.Caption:='';
for i:=0 to length(LabelKlartext.Caption)-1 do
        LabelVerschluesselt.Caption:=LabelVerschluesselt.Caption+Chr(Ord(LabelKlartext.Caption[i])+1);
end;

procedure TForm1.ButtonWiederEntschluesselnClick(Sender: TObject);
var i:integer;
begin
LabelWiederEntschluesselt.Caption:='';
for i:=0 to length(LabelVerschluesselt.Caption)-1 do
        LabelWiederEntschluesselt.Caption:=LabelWiederEntschluesselt.Caption+Chr(Ord(LabelVerschluesselt.Caption[i])-1);
Edit1.Text:=LabelWiederEntschluesselt.Caption;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
LabelKlartext.Caption:='LabelKlartext';
end;


Dadurch bekomme ich aber folgendes raus:

bei Verschlüsselt: MbcfmLmbsufy

bei wieder entschlüsselt: ÿLabelKlarte

Kann mir das jetzt mal bitte jemand erklären?


jaenicke - Sa 04.07.09 12:37

Der erste Buchstabe in einem String hat den Index 1...
// EDIT: Tippfehler... :autsch:


Popov - Sa 04.07.09 12:38

Bedenke bitte, daß es sowas wie Steuerzeichen gibt. Somit kann durch das Verschieben des Zeichens ein Steuerzeichen in den String rutschen. Solange du ganze Bytes verschlüsselst, ist das nicht wild, aber bei reinen Texten kann der Text irreparabel zerstört werden. Mal ein Beispiel:


Delphi-Quelltext
1:
s := 'abcd' + #0 + 'efghi';                    


Auch wenn der String aus 10 Zeichen besteht, ist beim fünften Zeichen schluß. #0 ist immer Stringende, also wird auch nicht mehr angezeigt.


jaenicke - Sa 04.07.09 12:40

So lange man nur um eins verschiebt, kommt man aber von den Buchstaben (Asciicode >= 65) kaum auf die Steuerzeichen (Asciicode <= 32).


Popov - Sa 04.07.09 12:41

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Der erste Buchstabe in einem String hat den Index 0...


Verwechselst du da nicht etwas? Eigentlich ist das erste Zeichen immer 1. Somit ist das nicht richtig:


Delphi-Quelltext
1:
for i:=0 to length(LabelKlartext.Caption)-1 do                    


Das wäre richtig:


Delphi-Quelltext
1:
for i:=1 to length(LabelKlartext.Caption) do                    


jaenicke - Sa 04.07.09 12:42

Ja, genau das wollte ich damit sagen, aber dann hab ich mich vertippt. :autsch:


Popov - Sa 04.07.09 12:45

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
So lange man nur um eins verschiebt, kommt man aber von den Buchstaben (Asciicode >= 65) kaum auf die Steuerzeichen (Asciicode <= 32).


In der Regel hast du Recht, aber es gibt auch Sonderzeichen. ÿ ist zB 255, beim Rollen wird daraus #0.


Edit: Nachtrag

@ffgorcky

Beim ShortString wird die 0 Position für die Länge des Strings genutzt. Somit hast du den Wert durch i := 0 mit verarbeitet. Welcher Wert da beim AnsiString steht weiß ich nicht, wahrscheinlich #0, da AnsiString die Länge anders verwaltet.


newbie333 - Sa 04.07.09 18:09

Vielen Dank @ Popov :)


newbie333 - So 05.07.09 14:16

Das ist ja jetzt total unsicher..
Kann mir jemand erklären, wie man das ganze jetzt etwas sicherer bekommt? :)
Also das man zum Beispiel nen Schlüssen eingeben muss..
zb das man die Stelle [n] des verschlüsselten Textes nochmal irgendwie dazwischen macht oder so?


Vielen Dank schonmal!


Popov - So 05.07.09 16:09

Eine Möglichkeit auf die Schnelle.


Delphi-Quelltext
1:
2:
3:
const
code = 'ghijklmnopqrstuvwxyzabcdef';
//     'abcdefghijklmnopqrstuvwxyz';


Du arbeitest nicht mit einer Konstante, sondern nimmst eine Variable und addierst dein Kennwort zu einer 26 lange Zeichenkette zusammen (nur aus Kleinbuchstaben). Beispiel:

aus dem Kennwort

"maxundmoritz"

machst du eine Zeichenkette

"maxundmoritzmaxundmoritzma"

und diese benutzt du statt

"ghijklmnopqrstuvwxyzabcdef"

Somit hast du eine Verschlüsselung die abhängig vom Kennwort ist.

Allerdings gehe ich nicht noch tiefer ins Detail, da diese Art der Verschlüsselung sowieso eine Sackgasse ist. Du warst es der mit dem Konzept gekommen ist, wir haben es nur optimiert.

Aber auch wenn du es besser machst, es wird nicht viel besser. Dieses Buchstabentauschen kriegt man schnell berechnet. Also entweder es ist dir egal und dir reicht deine oder eine Xor Verschlüsselung, oder du benutzt einen professionellen Algorithmus.


elundril - So 05.07.09 16:15

user profile iconPopov hat folgendes geschrieben Zum zitierten Posting springen:
Eine Möglichkeit auf die Schnelle.
aus dem Kennwort

"maxundmoritz"

machst du eine Zeichenkette

"maxundmoritzmaxundmoritzma"

und diese benutzt du statt

"ghijklmnopqrstuvwxyzabcdef"

Somit hast du eine Verschlüsselung die abhängig vom Kennwort ist.


besser:

du nimmst das kennwort zum verschlüsseln:

maxundmoritz

und wenn du damit fertig bist hängst du es nicht einfach nochmal dran, sondern deinen text zum verschlüsseln

maxundmoritzhalloichbinderwalter und so weiter.

damit vermeidest du periodizität.

lg elundril


Sirke - Mo 06.07.09 11:26

Aus dieser Monoalphabetischen Substitution kann man sehr einfach eine Polyalphabetische Substitution machen, indem man den Wert für die "Verschiebung der Zeichen" nicht Konstant hält, sondern von einem Schlüssel abhängig macht.

Dies kann man sehr leicht realisieren, indem man die selben Anweisungen vom Klartext für den Schlüsel(text) benutzt um die Zeichennummer auszulesen, welche dann als Verschiebungszahl funktioniert.

Bei einem Schlüssel, der die selbe Länge wie der Klartext hat, bekommt man damit eine 100%ige Sicherheit!!! ;-)
(Leider eben auf Kosten der Schlüssellänge)


Anstatt dieser Variante mit einem eben so langen Schlüssel wie Klartext kann man auch auf einen kürzeren Schlüssel setzen, welcher dazu dient einen Schlüsselstrom zu erzeugen. Dazu benötigt man dann einen möglichst guten Zufallsgenerator, welcher mit dem Schlüssel initialisiert wird.


axellang - Mo 06.07.09 16:43

Hallo newbie333,

ich habe Dir ein kleines Projekt (erstellt in D2007) angehängt was eine einfache Verschlüsselung veranschaulicht.

Gruß

Axel


newbie333 - Di 07.07.09 09:17

VIELEN VIELEN DANK! :)
Das Forum ist echt Klasse!

Das Programm läuft bei mir aber leider nicht, hab nur Delphi 5 von der Schule bekommen ;)
Danke trotzdem!


axellang - Di 07.07.09 14:25

Hi,

user profile iconnewbie333 hat folgendes geschrieben Zum zitierten Posting springen:

Das Programm läuft bei mir aber leider nicht, hab nur Delphi 5 von der Schule bekommen ;)
Danke trotzdem!


damit es mit Delphi 5 funktioniert musst Du in der Projektdatei "Crypt.dpr"
folgendes auskommentieren oder löschen: "Application.MainFormOnTaskbar := True;".

Außerdem musst Du in der crmain.pas unter uses den Verweis auf die Unit Variants rausnehmen.

Beim laden des Projekts in D5 kommt zwar noch eine Fehlermeldung das Panel1.DesignSize nicht existiert
aber dass kannst Du getrost wegklicken. Wenn Du es wie beschrieben abänderst, lässt sich das Projekt auch unter
D5 kompilieren und ausführen (habe es eben selbst ausprobiert [D5 Enterprise]).

Axel