Entwickler-Ecke

Algorithmen, Optimierung und Assembler - strings (speziell chars) mathematisch verschlüsseln !?


g1o2k4 - Sa 13.01.07 16:47
Titel: strings (speziell chars) mathematisch verschlüsseln !?
hallo

ich beschäftige mich grad mit verschlüsslungsverfahren und komme nicht weiter.
ich habe mathematische algorithmen um sachen zu verschlüsseln. mit zahlen kein problem. aber wie wandele ich buchstaben in zahlen oder binär code um ? reicht strtoint ?
am besten wäre sowas in der art:


Delphi-Quelltext
1:
2:
3:
4:
for i:=1 to length(s) do
      begin
        s[i]:=char(strtoint(Edit1.text) Xor Ord(s[i]));
      end;


das ist eine einfache xor "verschlüsslung/vertauschung". edit1 ist der schlüssel bzw um wieviel stellen im asci zeichensatz der buchstabe des wortes "s" an der stelle "i" verschoben werden soll.
das geschieht ja eigentlich auch mathematisch, wobei s[i] anscheinend in eine zahl umgewandelt wird sonst würde es ja nicht funktionieren oder ?

könnte ich jetzt mit Ord(s[i]) auch andere mathematische operationen durchführen (potenzieren, logarithmieren, multiplizieren oder was weiß ich...) ?

oder gibt es eine spezielle funktion chartoint ?


jaenicke - Sa 13.01.07 16:53

Chr und Ord sind schon richtig, denn sie geben dir den Ascii-Code des jeweiligen Zeichens zurück, bzw. wandeln diesen wieder in ein Zeichen um.


g1o2k4 - Sa 13.01.07 17:08

achso.
wäre denn folgendes richtig ?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var a:integer; // variable für weitere rechungen
    x:integer; // variable für weitere rechnungen
    b:string// text "abc" oder so...
    c:string// verschlüsseltes wort "bcd"

    a := Ord(b[i]);   // buchstabe des wortes "b" an der stelle "i" in asci zeichen umwandeln

    x := a * 2398;    // mathematische operation mit dem buchsten b[i], ergebnis speichern in "x"

    c[i] := char(x);  // ergebnis der operation an stelle c[i] der neuen und verschlüsselten wortes speichern

    edit1.text := c;  // verschlüsseltes wort als string ausgeben


oder wie muss der code für diesen oder einen ähnlichen ablauf lauten ?


grüße g1o


JayEff - Sa 13.01.07 17:10
Titel: Re: strings (speziell chars) mathematisch verschlüsseln !?
user profile icong1o2k4 hat folgendes geschrieben:
oder gibt es eine spezielle funktion chartoint ?

Jap, sie heißt "ord()" ;)

Das Problem an der xor verschlüsselung, auf das ich schonmal hingewiesen hab, ist das folgende, mal völlig aus dem Kontext gerissen ^^:
ich hat folgendes geschrieben:
wie schon gesagt, bei einer undglücklichen kombination mit xor kannst du eof bekommen. eof=end of text, dieses Zeichen sagt deinem TFileStream, der die Datei lädt, dass der Text zuende ist und alles weitere Laden sinnlos ist, du erhälst eine unvollständige verschlüsselte Highscore. Statt SizeOf kannst du auch einfach irgendeine Zahl schreiben, xor kannst du dir vorstellen wie ein Rechenzeichen, - + * div ( / ) und so weiter. Bei xor musst du dir das folgendermaßen denken:
Der PC rechnet ja mit Bits, also einsen und nullen. Stellt man eine normale Zahl, wie z.B. 10 im Binärsystem dar, erhält man 1010
von links nach rechts: die Anzahl von 8er, 4er, 2er, 1er in der Zahl. also: 1 8er und 1 2er.
Nehmen wir eine andere Zahl... 13 z.B. 1101

Wendet man nun ein Rechenzeichen wie xor an, vergleicht man immer übereinanderstehende 1en und 0en. Wie xor funktioniert steht hier: Suche in Wikipedia XOR.
Die Berechnung ist also

Quelltext
1:
2:
3:
4:
    1010 
xor 1101 
-------- 
    0111

Wir erhalten eine 7.
Nehme ich größere Zahlen kommen die unterschiedlichsten Ergebnisse heraus: Quelltext markieren

Quelltext
1:
2:
3:
4:
    10110010 = 178 
xor 01001101 =  77 
------------ 
    11111111 = 256



Aber:

Quelltext
1:
2:
3:
4:
    10110010 = 178 
xor 10101010 = 170 
------------ 
    00011000 =  24 (nur!)


Das Problem: wenn 04 (hex) rauskommt, hast du ein EOT. Um das zu verhindern, benutze verschlüsselungen wie + und - (wie beim caesar) mit einigermaßen kleinen Verschiebungen. Alternativ kannst du natürlich bei deiner Xor bleiben - dann solltest du allerdings beim Laden der Daten mit TFileStreams arbeiten.. ähm ... ich kann aber nichtmal dabei garantieren, dass es funktioniert...
Naja, um Probleme zu vermeiden, wird dir wahrscheinlich sogar eine Verschiebung (plus/minus) um 10 reichen, denn dann wird keine Zahl mehr in eine andere überführt und die datei wird wirklich unleserlich
Vorteil der Xor ist halt, das hin- und rückweg die selbe operation ist, aber es ist nicht wirklich schwer, bei der Verschlüsselung ein + und bei der Entschlüsselung ein - in den Quelltext zu schreiben


Soviel zu Char/Ord und Xor.

Du möchtest jetzt das Wort im Edit1 als Schlüssel benutzen? Dann vermute ich mal, dass du jeden Klartextbuchstaben mit einem Buchstaben des Schlüsselwortes verschlüsseln willst. Das würdest du dann so machen, dass du innerhalb der for-Schleife eine weitere Zählvariable hochzählst, bis sie die Länge des Schlüsselwortes hat, dann setzt du sie wieder auf 1 zurück.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
counter:=0;
for i:=1 to length(text) do
begin
   inc(counter);
   text[i]:=char(ord(key[counter]) xor ord(text[i]));
   if counter = length(key) then
      counter:=0;
end;
Dabei erhälst du so eine Verschlüsselung:

Quelltext
1:
2:
HALLOHALLOHALLOHA
Dies ist ein Text

Wobei das D mit einem H, das o mit einem A etc. verschlüsselt wird.
StrToInt funktioniert nur, um eine Zahl wie '1234' in eine Integervariable umzuwandeln.

Dabei möchte ich nochmal auf die Problematik von Xor hinweisen und dir eine simple verschiebung enpfehlen (einfach beim verschlüsseln das xor mit einem +, beim entschlüsseln mit einem - ersetzen, und statt char(, char(byte( schreiben), die ist beinah genauso sicher, da auch eine polyalphabetische Verschlüsselung. Beide Verfahren haben die gleichen Schwächen, ausser, dass beim +/- mit großer Wahrscheinlichkeit kein EOT bei rauskommt, soviel weiß ich aus eigener Erfahrung.


jaenicke - Sa 13.01.07 17:14

user profile icong1o2k4 hat folgendes geschrieben:
[delphi] c[i] := char(x); // ergebnis der operation an stelle c[i] der neuen und verschlüsselten wortes speichern
(...)
oder wie muss der code für diesen oder einen ähnlichen ablauf lauten ?

Ich habe Chr geschrieben! Das war kein Schreibfehler! Was du mit char() machst, ist, den Integer-Wert nach char zu casten. Du willst aber das Gegenstück zu Ord. Und das heißt Chr. Es kommt aber vielleicht dasselbe heraus...

// EDIT: Ansonsten: Ja, ist so richtig!


wulfskin - Sa 13.01.07 17:18

user profile iconjaenicke hat folgendes geschrieben:
Was du mit char() machst, ist, den Integer-Wert nach char zu casten. Du willst aber das Gegenstück zu Ord. Und das heißt Chr. Es kommt aber vielleicht dasselbe heraus...
Ja das ist genau das selbe...


g1o2k4 - Sa 13.01.07 17:28

danke für die antworten !

@jaenicke:
also so ?

Delphi-Quelltext
1:
2:
3:
4:
5:
var a:integer;
    b:string:

    a := ord(b);  // angenommen man will ein ganzes wort übertragen...
    b := chr(a);


so richtig ?



@JayEff:

danke für diesen ausführlichen kommentar !
das funktionsprinzip von eor bzw xor ist mir bewusst, aber nicht die nachteile.
dann ist eof so etwas wie in der programmiersprache "C" die "endekennung 0" oder ?

d.h. um diese tatsache zu vermeiden könnte ich auch einfach eine verschlüsslung mit ord() und chr() und +/-/:/* schreiben... !?
wäre wohl das beste, aber das programm das ich schon geschrieben habe soll ja nur als beispiel dienen und es ist eigentlich schon fertig (Xor ver und entschlüsslung + entschlüsslungsüberprüfung mit wörterbuch).
also wie gesagt fürs zeigen reicht xor denke ich.

grüße g1o


JayEff - Sa 13.01.07 17:33

user profile icong1o2k4 hat folgendes geschrieben:


Delphi-Quelltext
1:
2:
3:
4:
5:
var a:integer;
    b:string:

    a := ord(b);  // angenommen man will ein ganzes wort übertragen...
    b := chr(a);

Nicht ganz. Der Unterschied zwischen Char und String ist einfach, dass ein String mehrere Chars hintereinander ist. Ich glaube, du kannst die zuweisung AString := AChar schon machen, aber es führt zu Problemen bei ord(b), da b kein Char ist. Hier musst du nur b[1] (das erste Zeichen) benutzen, schon gehts. Du brauchs diesen Index IIRC auch, wenn b nur aus einem Zeichen besteht!


g1o2k4 - Sa 13.01.07 17:43

user profile iconJayEff hat folgendes geschrieben:

Nicht ganz. Der Unterschied zwischen Char und String ist einfach, dass ein String mehrere Chars hintereinander ist. Ich glaube, du kannst die zuweisung AString := AChar schon machen, aber es führt zu Problemen bei ord(b), da b kein Char ist. Hier musst du nur b[1] (das erste Zeichen) benutzen, schon gehts. Du brauchs diesen Index IIRC auch, wenn b nur aus einem Zeichen besteht!



also besser

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
var a:integer;
    b:string:
    
    for i=1 to length(b) do
    begin
      a := ord(b[i]);  // angenommen man will ein ganzes wort übertragen...
      b[i] := chr(a);  
    end;


so ? sprich buchstabe für buchstabe ?


jaenicke - Sa 13.01.07 17:44

Genau so! Das ist richtig!


g1o2k4 - Sa 13.01.07 17:51

user profile iconjaenicke hat folgendes geschrieben:
Genau so! Das ist richtig!


spitze dann kanns ja weiter gehn ;)

@JayEff: ach ja vorhin vergessen. wozu ist der counter, in deinem beispiel ?


ich meine das hier:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
counter:=0;
for i:=1 to length(text) do
begin
   inc(counter);
   text[i]:=char(ord(key[counter]) xor ord(text[i]));
   if counter = length(key) then
      counter:=0;
end;


jaenicke - Sa 13.01.07 17:54

Naja, wenn der Schlüssel bspw. 3 Zeichen lang ist, dann muss er ja alle 3 Zeichen wiederholt werden. Der Index des zu benutzenden Buchstaben aus dem Schlüssel fängt also wieder von vorne an...


JayEff - Sa 13.01.07 17:54

da ich davon ausgehe, dass key kürzer ist als text, und der key für den text immer wieder wiederholt wird:

Quelltext
1:
2:
HALLOHAL key
EIN TEXT text

Der counter darf natürlich nicht größer sein als die länge von key, da er dann auf ein nicht vorhandenes Zeichen zugreifen will. Darum kann ich auch nicht i nehmen, sondern brauche eine extra variable