C++ Verschlüsselungsprogramm // Suchen und Ersetzem

Prestige__

Mitglied
Hallo. Ich habe eine neue Frage, und zwar:
Ich würde gerne eine kleine Art Verschlüsselungstool erstellen. Ich erkläre mal was es machen sollte:

In einer Datei (test.dat) steht zB Hallo. Dieses Hallo soll ersetzt werden, also so in der Art:

1=H
2=a
3=l
4=o
5=!
6=.
......

Also es soll dem Programm klar gemacht werden das 1 zb H ist und es soll aus der Datei jedes H mit einer 1 ersetzen. Also sollte in der Datei 'test.dat' statt "Hallo" dann "12334" stehen. Wie kann ich das genau in C++ umsetzen?
 

sheel

I love Asm
Hi

ist die Zuordnung fix im Programm? Oder auch in einer Datei?
Sind 1234 als lesbare Ziffern gedacht, und falls ja, wie stellst du es dir vor, wenn es mehr als 10 verschiedene Zeichen gibt?

Codemäßig wäre zuerst einmal eine Funktion, die ein einzelnes Byte etc. "übersetzt" gut - wie das am einfachsten gemacht wird hängt von den Fragen oben ab.

Dann ... Zwei Dateien "in" und "out" öffnen, nach und nach alle Bytes der in-Datei einlesen. und für jedes Byte einmal die Übersetungsfunktion aufrufen und das Ergebnis in die out-Datei schreiben. Falls du schon mit Dateien zu tun hattest, mit welchen Funktionen hast du gearbeitet (es gibt je einige Varianten)?

PS: Nur damit keine falschen Vorstellungen entstehen, diese Verschlüsselung ist komplett unsicher. Aber eine nette Übungsaufgabe.
 

Prestige__

Mitglied
Also im Programm soll alles registriert werden wie halt eben 1=h, 2=a, .... In der Datei steht dann zb eine Zusammenfassung eines Buches und jeder Buchstabe h soll mit 1 ersetzt werden, jedes a mit 2, usw..... Da es ja viele Buchstaben und Zeichen gibt, habe ich mir das auch so vorgestellt zwei bis dreifache ziffern zu nehmen. zb m=132, p=834, ....

Ich hatte Dateien immer mit fstream geöffnet, gelesen und geschlossen.
C++:
fstream f;
                  f.open("username.dat", ios::in);
                  f >> username;
                  f.close();

PS: Nur damit keine falschen Vorstellungen entstehen, diese Verschlüsselung ist komplett unsicher. Aber eine nette Übungsaufgabe.
Ich weiß das es keine Sichere verschlüsselung wäre aber ich mache das eben als Hobby mit dem Programmieren und ich stell mir gerne immer mal solche Aufgaben, und es wäre sicher auch mal ein kleines, vielleicht nützliches Tool mal gewisse Dinge evt mal leicht zu sichern ^^
 

sheel

I love Asm
Also, dann gibt es im Programm ein Array mit 256 Elementen (für jedes Byte einen), welche Bytenummer in welche Zahlenfolge übersetzt wird.
Code:
std::string dasArray[256] ;
dasArray[0] = "123";
dasArray[1] = "321";
//usw.
dasArray['a'] = "001";
dasArray['b'] = "747";
//usw.
dasArray['h'] = "002";
//usw.
Wird ziemlich lang

Als Übersetungsfunktion kann dann dafür etwas einfaches her:
Code:
std::string encrypt(unsigned char c)
{
    //bekommt eben einen Bytewert (0-255) und soll die "verschlüsselte" Variante zurückgeben
    return dasArray[c];
}

Was die Dateien angeht scheinst du dich schon auszukennen ...
 

Prestige__

Mitglied
hm den oberen Teil mit dem arrays zum regestrieren versteh ich, aber das mit der Übersetzungsfunktion hängt grad ein wenig :/
 

cwriter

Erfahrenes Mitglied
Ein bisschen Theorie dazu:

Also es soll dem Programm klar gemacht werden das 1 zb H ist und es soll aus der Datei jedes H mit einer 1 ersetzen.
Ok. Wenn wir mal extended ASCII (256 Zeichen) nehmen, hat dein "dem Programm Klarmachen" eine Schlüsselkomplexität von O(256), abzüglich der Nicht-druckbaren oder nicht verwendeten Zeichen wohl noch etwa O(150), d.h. dein Schlüssel wäre bei mittellangen Nachrichten mit zufälliger Verteilung etwa 150 Zeichen lang.


Ich weiß das es keine Sichere verschlüsselung wäre aber ich mache das eben als Hobby mit dem Programmieren und ich stell mir gerne immer mal solche Aufgaben, und es wäre sicher auch mal ein kleines, vielleicht nützliches Tool mal gewisse Dinge evt mal leicht zu sichern
Gegen Teil 1 lässt sich nichts sagen. Teil 2: Nein, sicher nicht. Du sicherst damit gar nichts. Du hast nichts anderes als eine Substitution Cipher im Kopf. Selbst wenn du den Schlüssel nicht speicherst (was du ja wahrscheinlich tun wirst, weil wie schon angemerkt dein Schlüssel oft 150 Zeichen lang sein wird), lässt dies eine Häufigkeitsanalyse zu, und zusammen mit einigen Wörterbuchabgleichen bist du sehr schnell im Territorium von fast konstantem Entschlüsselungsaufwand. (Die "starke" Schlüssellänge von 150 Bytes verhindert immerhin Brute-Force von O(150!)).

Eine gute Übung wäre auch ein Programm, das solche Verschlüsselungen knackt.

Also, dann gibt es im Programm ein Array mit 256 Elementen (für jedes Byte einen), welche Bytenummer in welche Zahlenfolge übersetzt wird
Aus diesem Grund wird in der Praxis ein Pseudo Random Number Generator mit einem gesalzenem und gehashtem Passwort als Seed benutzt (Siehe IV, Initialization Vector). Dadurch kann die Schlüssellänge stark gekürzt werden, ohne nennenswert an Sicherheit einzubüssen.

Allerdings, @sheel: Wenn du ohnehin einzelne Bytes ersetzt, warum dann ins Dezimalsystem übersetzen? Da ohnehin keine Doppelbelegung möglich sein kann, wäre ja ein einfaches shuffelling genug:
C++:
char table[256];
char key[256]; //Vorher gesetzt
for(size_t i = 0; i < 256; ++i)
    table[i] = key[i];

(Ich sehe schon die Motivation hinter der Lesbarkeit, aber wenn du ohnehin alle Bytewerte ersetzen willst, war der Ausgangswert ja auch nicht lesbar. Und zu Übungszwecken sind einzelne Bytes wohl einfacher. Und ich sehe schon
Da es ja viele Buchstaben und Zeichen gibt, habe ich mir das auch so vorgestellt zwei bis dreifache ziffern zu nehmen. zb m=132, p=834, ....
aber ich sehe mit diesem Verfahren nur Nachteile.
)

hm den oberen Teil mit dem arrays zum regestrieren versteh ich, aber das mit der Übersetzungsfunktion hängt grad ein wenig :/
encrypt ist eine Funktion von char => std::string, wobei jedes Byte zu einem vordefinierten String übersetzt wird (ein Mapping).
Du musst nur jedes einzelne Byte der Eingabedatei in die Funktion füttern und die Ausgabe in eine andere Datei schreiben.

Gruss
cwriter