Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Binärcodeumwandlung


Gilbert111 - Fr 29.10.10 13:09
Titel: Binärcodeumwandlung
hallo,

ich bin grade dabei an einem Verschlüsslungsprogramm zu arbeiten (simple xor-verschlüsselung).
Hierzu muss ich zunächst eine Funktion schreiben, die mir einen String in einen Binärcode umwandelt.
Da ich mir nicht besser zu helfen wusste habe ich das ganze von hand mit einer case of funktion gemacht.
Starte ich nun das Testprojekt zur Umwandlung bekomme ich folgende Fehlermeldung:
"Im Projekt Bin.exe ist eine Exception der Klasse EAccessViolation aufgetreten.[...]"
Hier der Code:


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:
unit uBin;

interface

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

type
  TIntegerArray = array of integer; //Erstellte Klasse um die Ausgabe eines Arrays aus einer Funktion zu ermöglichen
  TForm1 = class(TForm)
    EPlain: TEdit;
    BBin: TButton;
    LBBin: TListBox;
    procedure BBinClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function Transform(plain:string): TIntegerArray;
var lp, i :integer;
        x :TIntegerArray;
begin
  lp:=Length(plain);
  for i:=1 to lp do
  begin
    case plain[i] of
    'a': x[i]:='00000';
    'b': x[i]:='00001';
    'c': x[i]:='00010';
    'd': x[i]:='00011';
    'e': x[i]:='00100';
    'f': x[i]:='00101';
    'g': x[i]:='00110';
    'h': x[i]:='00111';
    'i': x[i]:='01000';
    'j': x[i]:='01001';
    'k': x[i]:='01010';
    'l': x[i]:='01011';
    'm': x[i]:='01100';
    'n': x[i]:='01101';
    'o': x[i]:='01110';
    'p': x[i]:='01111';
    'q': x[i]:='10000';
    'r': x[i]:='10001';
    's': x[i]:='10010';
    't': x[i]:='10011';
    'u': x[i]:='10100';
    'v': x[i]:='10101';
    'w': x[i]:='10110';
    'x': x[i]:='10111';
    'y': x[i]:='11000';
    'z': x[i]:='11001';
    else exit;
    end;
  end;
  Result:=x;
end;

procedure TForm1.BBinClick(Sender: TObject);
var plain:string; x:TIntegerArray;
    i, lp : integer;
begin
  plain:=Form1.EPlain.Text;
  lp:=length(plain);
  x:=Transform(plain);
  for i:=1 to lp do
  begin
    Form1.LBBin.Items.Add(IntToStr(x[i]));
  end;
end;



end.


Könnt ihr da den Fehler entdecken?

Vielen Dank schon im Vorraus! :)


guinnes - Fr 29.10.10 13:13

user profile iconGilbert111 hat folgendes geschrieben Zum zitierten Posting springen:
Könnt ihr da den Fehler entdecken?
Ja, nicht nur den sondern die :

1. Geht das Zeug so, wie es hier steht, gar nicht durch den Kompiler
2. Du hast ein IntegerArray, versuchst aber Strings reizutun
3. Du hast die Länge von dem IntegerArray nicht gesetzt
4. Kuck dir mal Ord an


freedy - Fr 29.10.10 13:22

Du weißt schon, was lokale Variablen sind, oder?

Ich nehme einmal an, dass dir dein Programm mit einem Fehler aussteigt, richtig? Wann setzt du denn die Array-Länge?


Gilbert111 - So 31.10.10 14:13

sorry... ich bin ein ziemlicher Anfänger.
wie setze ich denn die länge der arrays?
das mit dem string hab ich nur vergessen wieder zu ändern (ich wollte sehen ob ich den gleichen fehler bekomme wenn ich das mit nem string an statt von nem integer-array mache; antwort: ja)
ord gibt mir ja keinen binärcode mit dem ich dann xor-rechnen kann, oder?
ich habe mir schon gedacht dass es irgendwie an der "verlinkung" zwischen prozedur und funktion liegen wird...
ja er steigt aus wenn ich den button betätige...

könnt ihr mir bitte die konkreten stellen nennen wo ich was verändern muss? :)

vielen dank auf jeden fall!


jaenicke - So 31.10.10 14:22

Beachte einfach die Fehlermeldungen (und Warnungen!) vom Compiler, der sagt dir schon wo was falsch ist...

Naja, du willst die Länge setzen. Auf englisch also? Richtig: SetLength

Ja, und dann zu deinem seltsamen Konstrukt: Wie wäre es, wenn du die Umrechnung mathematisch angehst statt alles manuell einzutragen? Das ist schließlich einfache Mathematik.


Tranx - So 31.10.10 14:50

Das sollte eigentlich gehen. Mit dem Vorteil, dass Du die Codierung frei wählen kannst, steht in Codetext. Wenn Du willst, kannst Du sie als globale Konstante oder gar als Variable erstellen, wobei Du im letzten Fall dann den Code eingeben musst.

Die Variable j benötigst Du, um den Durchlauf durch den Codetext zu gewährleisten.

Beispiel (kein Delphi-Text!!)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
Text: 'Was steht hier?' (hier s)
Code: 'Codewort'        (hier CW) 


Zeichenwert     ASCII 
s     CW      s   CW  transf. transf. Z. 
W     C       87    67  20        
a     o       97   111  14        
s     d      115   100  23        
      e       32   101  69        E
s     w      115   119  4          
t     o      116   111  27        
e     r      101   114  23  
h     t      104   116  28   
t     C      116    67  55        7
      o       32   111  79        O
h     d      104   100  12  
i     e      105   101  12  
e     w      101   119  18        
r     o      114   111  29  
?     r       63   114  77        M


Die Codierung erfolgt im unten angegebenen Fall wie folgt:


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.BBinClick(Sender: TObject);
const 
  Codetext = 'Codewort';
var 
  plain: string
  i, j, lp, lc : integer;
begin
  plain:=Form1.EPlain.Text;
  lp:=length(plain);
  lc := Length(CodeText);
  j := 1;
  for i:=1 to lp do
  begin
    plain[i] := plain[i] xor codetext[j];
    j := ((j+1mod lc)+1;
  end;
  for i:=1 to lp do
  begin
    Form1.LBBin.Items.Add(IntToStr(plain[i]));
  end;
end;


Ich hoffe, das gibt Dir eine Anregung!


Gilbert111 - So 31.10.10 15:07

@Tranx: Vielen Dank erstmal für die viele Mühe!
den delphi code den du gepostet hast hab ich praktisch genauso im Verschlüsselungsteil des Programms. Was ich nicht verstehe ist, dass du in diesem fall ja praktisch chars verxorst oder? geht das?
der anfänglich von mir gepostete code sollte eine funktion sein um die strings (in deinem Fall plain und codetext) zu einem binären code mit in dem fall 5 bits zu transformieren. Oder ist das sinnlos und lassen sich die chars bzw. deren ord's einfach verxoren?

lg gilbert


jaenicke - So 31.10.10 15:14

Wenn es dir nur um das xor geht, dann geht das mit Zahlen, ja. Und ein Buchstabe ist ja nur ein bestimmter Zahlenwert. ;-)

Im Computer intern sind die Zahlen ohnehin binär gespeichert. Und da wird dann das xor direkt angewendet.


Gilbert111 - So 31.10.10 15:48

ahhh,
na ich bin ja auch klug... vielen dank, es war also alles mehr oder weniger umsonst :)

lg gilbert


Gilbert111 - So 31.10.10 16:45

also ich habe es jetzt noch einmal versucht.
chars lassen sich tatsächlich NICHT miteinander verxoren, da der "operator nicht auf diesen operandentyp anwendbar" ist.
Lasse ich aber die Zahlenwerte der Buchstaben miteinander xoren (ord(char) xor ord(char)) funktionierts.
das mit der parameterübergabe von prozedur und funktion funktioniert bei mir immer noch nicht, aber das sollte nicht zu schwer herauszufinden sein.

liebe grüße!


Tranx - So 31.10.10 17:55

Entschuldigung, daran habe ich echt nicht gedacht, aber die Lösung Char(Ord(plain[i]) xor ord(codewort[j])) klappt zum Glück.

War meion Fehler, ich habe den Code nicht geprüft.