ERLEDIGT
NEIN
NEIN
ANTWORTEN
26
26
ZUGRIFFE
19475
19475
EMPFEHLEN
-
Guten Abend,
Ich bin gerade dabei mit C++ eine Caesar Verschlüsselung (aus a wird b, aus b wird c usw.) zu erstellen. Allerdings bin ich noch nicht sehr erfahren in C++, daher könnte ich etwas Hilfe gebrauchen!
Wisst ihr vielleicht, wo es einen solchen Algorithmus für C++ bereits gibt?
Viele Grüße,
Cyraid
-
Hallo!
Ich weiß nicht genau wie gut du da so bist in C++ und der Kryptographie, aber ich hab da mal nen Artikel für dich der das alles gut beschreibt und den Algo enthält: http://www.linux-magazin.de/Artikel/...o/krypto1.html
Vielleicht hifts dir weiter!
Gruß Buba
-
Hallo!
Danke für deine Antwort Buba235!
Ich habe mir den Link angeschaut, aber komme leider nicht ganz zurecht damit.
Meine C++ Kentnisse sind wohl noch nicht ausreichend genug dafür..
Damit ihr euch ein Bild von meinem bisherigen Programm machen könnt, hier mal der Code:
Code :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
// main.cpp - Caesar Verschiebung #include <iostream> #include <conio> #include <stdio> using namespace std; int main() { int auswahl, i = 0; char klartext[50], geheimtext[50]; do { for(i = 0; i <= 50; i++) { klartext[i] = ' '; geheimtext[i] = ' '; } i = 0; clrscr(); cout << endl; cout << "- Caesar Verschiebung - v1.0" << endl << endl; cout << "Menueauswahl:" << endl; cout << "Nachricht verschluesseln [1]" << endl; cout << "Nachricht entschluesseln [2]" << endl; cout << "Programm beenden [3]" << endl << endl; cout << "Ihre Auswahl: "; cin >> auswahl; switch(auswahl) { case 1: cout << "Bitte zu entschluesselnde Nachricht (max. 50 Zeichen) eingeben: " << endl; cin >> klartext; while (klartext != '\0') { geheimtext[i] = ((klartext[i] + 1) % 256); i++; } cout << "Verschluesselte Nachricht lautet: " << endl << geheimtext << endl; break; case 2: cout << "Bitte zu entschluesselnde Nachricht (max. 50 Zeichen) eingeben: " << endl; cin >> geheimtext; while (geheimtext != '\0') { klartext[i] = (geheimtext[i] - 1); i++; } cout << "Entschluesselte Nachricht lautet: " << endl << klartext << endl; break; } } while(auswahl != 3); return 0;
Ich weiss, er ist sehr umständlich geschrieben, aber besser habe ich es nicht hinbekommen...
- Das Programm soll ein Menü beinhalten, in dem man sich entscheiden kann, ob man eine Nachricht ver- oder entschlüsseln will. (Verschiebung um 1. Stelle im Alphabet)
- Die Nachricht soll man eingeben können und darauf soll sie direkt ver- oder entschlüsselt angezeigt werden.
Nur leider klappt das mit meinem Programm hinten und vorne noch nicht!
Ich bekomme Fehlermeldungen wegen irgendwelchen Zugriffsverletzungen..
Könnt ihr mir weiterhelfen?
Viele Grüße,
Cyraid
-
Hallo!
Ich hab da noch was für dich gefunden. Vielleicht hilft dir das ja weiter: http://www.hackerboard.de/thread.php?threadid=17365
Gruß Buba
-
Das Problem ist deine Schleife (sowohl beim ver- als auch beim entschlüsseln)
Code c:1 2 3 4 5 6 7
i = 0; ...... while (klartext != '\0') { geheimtext[i] = ((klartext[i] + 1) % 256); i++; }
1. wenn du eine Laufvariable nutzt, dann mach mal besser eine for schleife
2. klartext ist nur ein Zeiger. So wie du das nutzen willst musst du noch bestimmen, welche Stelle von dem Array verglichen werden soll
3. das %256 kannst du dir sparen. char reicht nur von -128 bis 127. Wenn du einen Wert über 127 speicherst wird daraus von alleine einer aus dem negativen bereich
das ganze könnte dann so aussehen
Code c:1 2 3 4
for(int i = 0; klartext[i] != '\0'; i++) { geheimtext[i] = klartext[i]+1; }
soll das z eigentlich zu einem a werden? denn so wie du das atm machst, wird z nicht zu a
-
@Buba235
Vielen Dank für den Link. Ich habe mich dort umgeschaut und viele gute Ansätze und Tipps gefunden!
@Flegmon
Danke, dass du dir die Mühe gemacht hast, mein Programm anzuschauen!
Du hast Recht, was die Schleifen betrifft. Ich habe daher mein Programm noch einmal überarbeitet.
Voilà:
Code :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
// main.cpp - Caesar Verschiebung #include <iostream> #include <conio> #include <stdio> using namespace std; int main() { int auswahl, i = 0; char klartext[50], geheimtext[50]; do { for(i = 0; i <= 50; i++) { klartext[i] = ' '; geheimtext[i] = ' '; } clrscr(); cout << endl; cout << "\n- Caesar Verschiebung - v1.0" << endl << endl; cout << "Menueauswahl:" << endl; cout << "Nachricht verschluesseln [1]" << endl; cout << "Nachricht entschluesseln [2]" << endl; cout << "Programm beenden [3]" << endl << endl; cout << "Ihre Auswahl: "; cin >> auswahl; switch(auswahl) { case 1: cout << "Bitte zu entschluesselnde Nachricht (max. 50 Zeichen) eingeben: " << endl; cin >> klartext; for(i = 0; klartext[i] != '\0'; i++) { if(klartext[i] == 'z') { geheimtext[i] = 'a'; } else { if(klartext[i] == 'Z') { geheimtext[i] = 'A'; } else { geheimtext[i] = klartext[i] + 1; } } } cout << "Verschluesselte Nachricht lautet: " << endl << geheimtext << endl; break; case 2: cout << "\nBitte zu entschluesselnde Nachricht (max. 50 Zeichen) eingeben: " << endl; cin >> geheimtext; for(i = 0; geheimtext[i] != '\0'; i++) { if(geheimtext[i] == 'a') { klartext[i] = 'z'; } else { if(geheimtext[i] == 'A') { klartext[i] = 'Z'; } else { klartext[i] = geheimtext[i] - 1; } } } cout << "Entschluesselte Nachricht lautet: " << endl << klartext << endl; break; } } while(auswahl != 3); return 0; }
Mit deinem Tipp funktioniert es recht gut.
Ich habe zusätzlich 2 if-Verzweigungen eingebaut, um dem Problem, dass z nicht zu a wird, zu entgehen. Meine Lösung scheint mir aber nicht sehr elegant..
Ein weiteres Problem besteht darin, dass meine Zeichenanzahl auf 50 beschränkt ist. Wie kann ich sie unbeschränkt machen bzw. so einstellen, dass sie sich daraus ergibt, wieviel man eingibt?
Muss ich außerdem den Array klartext und geheimtext in einer for-Schleife durchlaufen lassen, um alle Zeichen auf "leer" zu setzen?
So wie ich es hier, am Anfang des Progamms, gemacht habe:
Code :1 2 3 4 5
for(i = 0; i <= 50; i++) { klartext[i] = ' '; geheimtext[i] = ' '; }
Beste Grüße
Cyraid
-
es wird sich kaum eleganter lösen lassen
Zitat von Cyraid
du hast hier verschiedene möglichkeiten. Die einfachste wäre wohl die Verwendung von std::string, da brauchst du dir um sowas eigentlich keine gedanken zu machen.
Zitat von Cyraid
Außerdem kannst du mit dem [] immer noch wie von arrays gewohnt umgehen
Kurz zur verwendung
Code cpp: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
#include <string> // NICHT string.h using namespace std; // damit du nicht std::string schreiben musst string text; cin>>text; /* zum Zugriff hast du mehrere Möglichkeiten (hier nur ein paar) 1. du kannst mit string[n] auf die stelle n zugreifen (wie bei einem array) 2. du kannst += benutzen um etwas hinzuzufügen (ans Ende) string s; s += "Hallo"; s += '1'; 3. wenn du nur 1 Zeichen hinzufügen willst (ans Ende), kannst du push_back benutzen s.push_back('a'); du musst nur drauf achten, bei einem Zeichen ' ' und bei mehreren " " zu benutzen Zugriff kann zB. so erfolgen */ for(int i = 0; i < klarText.length(); i++) { geheimText.push_back(klarText[i] + 1); }
wenn du ihn leer haben willst, ist das die einzige methode. Aber normalerweiße braucht man einen string nicht leeren
Zitat von Cyraid
-
@Flegmon
Vielen Dank für deine ausführlich Antwort und Erklärung!
Das mit string ist eine gute Idee. Mit push_back() klappt das auch wunderbar, allerdings ergibt sich daraus ein neues Problem.
Wenn mein Programm einmal durchgelaufen ist und man noch einmal auswählt eine Nachricht entschlüsseln zu wollen, werden die weiteren Zeichen an die der vorigen Nachricht dran gehängt, was natürlich sehr störend ist.
Um das zu vermeiden habe ich mir überlegt (wie du es auch schon erwähnt hast), den string wie ein array zu benutzen.
Also folgendermaßen:
Code :1 2 3 4 5 6
for(i = 0; i < klartext.length(); i++) { geheimtext[i] = klartext[i] + 1; } cout << "Verschluesselte Nachricht lautet: " << endl << geheimtext << endl;
Daraufhin wird mir allerdings nichts ausgegeben, als wäre nichts in geheimtext geschrieben worden. Habe ich einen Fehler bei der Verwendungs des strings gemacht? Mir wird kein Fehler angezeigt..
Hier noch einmal mein komplettes Programm (Die Entschlüsselung ist noch beim alten):
Code :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
// main.cpp - Caesar Verschiebung #include <iostream> #include <conio> #include <stdio> #include <string> using namespace std; int main() { int auswahl, i = 0; string klartext, geheimtext; do { clrscr(); cout << endl; cout << "\n- Caesar Verschiebung - v1.0" << endl << endl; cout << "Menueauswahl:" << endl; cout << "Nachricht verschluesseln [1]" << endl; cout << "Nachricht entschluesseln [2]" << endl; cout << "Programm beenden [3]" << endl << endl; cout << "Ihre Auswahl: "; cin >> auswahl; switch(auswahl) { case 1: cout << "Bitte zu entschluesselnde Nachricht (max. 50 Zeichen) eingeben: " << endl; cin >> klartext; for(i = 0; i < klartext.length(); i++) { geheimtext[i] = klartext[i] + 1; } cout << "Verschluesselte Nachricht lautet: " << endl << geheimtext << endl; break; case 2: cout << "\nBitte zu entschluesselnde Nachricht (max. 50 Zeichen) eingeben: " << endl; cin >> geheimtext; for(i = 0; geheimtext[i] != '\0'; i++) { if(geheimtext[i] == 'a') { klartext[i] = 'z'; } else { if(geheimtext[i] == 'A') { klartext[i] = 'Z'; } else { klartext[i] = geheimtext[i] - 1; } } } cout << "Entschluesselte Nachricht lautet: " << endl << klartext << endl; break; } } while(auswahl != 3); return 0; }
Viele Grüße,
Cyraid
-
Der string speichert intern seine länge. Wenn du mit [] die einzelnen zeichen setzt, verhindert der string, dass es eine zugriffsverletzung gibt, da es ja über die gespeicherte länge hinausgeht.
Wenn du den string löschen willst mach einfach string = "";
-
@Flegmon
Danke für deine Antwort!
Deine Antwort macht Sinn, eines ist mir dabei allerdings nicht ganz klar.
Der String sieht also eine Zugriffsverletzung, wenn ich mit [] ein einzelnes Zeichen setze.
Welche Länge bzw. welchen Speicher sieht er als verletzt, wenn ich ihn doch ohne Angabe einer Länge deklariert habe?
Code :1
string klartext, geheimtext;
Müsste die Länge des Strings sich nicht erst durch die Eingabe des Benutzers ergeben
Viele Grüße,
Cyriad
-
Ich hab mal nachgeschaut im Source Code.
Also mit der länge meine ich, die Länge der gespeicherten Daten.
Beim [] wird aber nicht überprüft, ob es eine Verletzung gibt. Mein Fehler sry.
Intern ist der string auch nur ein Array. Der hat am anfang eine gewisse größe (ich glaub je nach pc anders, aber passen schon recht viel zeichen rein). Und sobald man zuweit schreibt (also über die größe des Arrays hinaus) block die string Klasse das.
Ich hab jetzt nicht genauer nachgeschaut, wie die string klasse aufgebaut ist.
Wenn es dich interresiert, dann kannst du mal bei deinem include verzeichnis schauen,
da kannst du den ganzen source der stl anschauen.
-
@Flegmon
Ich versuche gerade das Programm mit dieser Variante zum Laufen zu bringen:
Code :1 2 3 4 5 6
for(i = 0; i < klartext.length(); i++) { geheimtext[i] = klartext[i] + 1; } cout << "Verschluesselte Nachricht lautet: " << geheimtext << endl;
Allerdings bekomme ich keine Ausgabe des Strings geheimtext, stattdessen eine Meldung
"main.cpp": W8012 Vergleich von signed- und unsigned-Werten in Funktion main() in Zeile 32".
Zeile 32 ist folgende:
Code :1
for(i = 0; i < klartext.length(); i++)
Ob dadurch nichts in den String geheimtext geschrieben wird?
Wie könnte man diesen Fehler beheben?
Zum include Verzeichnis und dem Source Code.
Ich kann dir da nur teilweise folgen, da stößt mein C++ Wissen leider schon an seine Grenzen.
Ich habe einen Blick in die header-Datei von string riskiert, kann aber nicht viel mit dem Inhalt anfangen.
Viele Grüße,
Cyraid
-
zu den headern,
wenn du dev-c++ benutzt, kannst du nich viel in dem header nachschauen, da dort der Zeilenumbruch nicht richtig angezeigt wird. Aber wenn du noch keine templates kennst,
bringt es dir sowieso noch nicht viel da zu schauen.
Zu deinem Problem. Die Meldung ist nur eine Warnung, es sollte trotzdem funktioniere.
Nutze lieber die Variante davor und setze die string nach jedem durchlauf zurück...
-
@Flegmon
Erstmal: Danke wieder für deine Antwort!
Ich benutze den C++ BuilderX. Die Header-Dateien werden mir mit Zeilenumbruch, also richtig, dargestellt. Ich verstehe allerdings trotzdem nicht sehr viel davon, nur sehr sehr vage.
Ich habe, wie du vorgeschlagen hast, wieder die vorherige Variante benutzt, die mit push_back(). Funktioniert auch einwandfrei, nur komme ich nun wieder an mein altes Problem..
Ich musste nämlich auch bei dieser Variante wieder auf ein paar Zeichen mittels [] zugreifen, um von 'z' zu 'a' zu kommen. Doch das funktioniert, wie oben schon, leider nicht.
So sieht meine for-Schleife zur Verschluesselung nun aus:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
for(i = 0; i < klartext.length(); i++) { if(klartext[i] == 'z') { geheimtext[i] = 'a'; } else { if(klartext[i] == 'Z') { geheimtext[i] = 'A'; } else { geheimtext.push_back(klartext[i] + 1); } } }
Wenn ich bei dieser Variante ein 'z' eingebe passiert, so scheint es, im geheimtext String nichts.
Hier ein Auszug aus dem laufenden Programm:
Bitte zu entschluesselnde Nachricht (max. 50 Zeichen) eingeben:
abza
Verschluesselte Nachricht lautet: bcb
Wie du siehst, wird die Stelle mit dem 'z' bei der Verschlüsselung ganz übersprungen.
Wo steckt der Fehler?
Oder gibt es eine Möglichkeit das zu umgehen?
Viele Grüße,
Cyraid
-
Ich habs jetzt mal ausprobiert. Das problem is wirklich das, dass er intern die länge speichert. Hab aber einen sehr einfachen weg gefunden es zu umgehen. Man kann die länge nämlich manuel ändern.
Versuchs mal mit
geheimtext._Mysize++;
nach geheimtext[i] = 'A';
das könnte evtl. funktionieren
EDIT: da fällt mir ein, warum baust du nicht schon beim verschlüsseln folgendes ein:
Code cpp:1 2 3 4
if(klartext[i] == 'z') geheimtext.push_back('a'); else geheimtext.push_back(klartext[i]+1);
Geändert von Flegmon (07.06.06 um 13:18 Uhr)
Ähnliche Themen
-
Caesar Verschlüsselung mit Buchstaben
Von Punish im Forum C/C++Antworten: 8Letzter Beitrag: 21.05.10, 10:47 -
Verschlüsselung
Von chrisjahl im Forum InternetkommunikationAntworten: 2Letzter Beitrag: 26.10.08, 23:40 -
Verschlüsselung mit C#
Von aquasonic im Forum .NET ArchivAntworten: 5Letzter Beitrag: 27.07.05, 13:02 -
Caesar-Verschlüsselung
Von laaars im Forum Delphi, Kylix, PascalAntworten: 2Letzter Beitrag: 23.03.04, 12:56 -
Algorithmus für Caesar Code gesucht...
Von Henderwaeldler im Forum Coders TalkAntworten: 5Letzter Beitrag: 26.10.03, 15:47





Zitieren
Login






