Caesar Verschlüsselung - Algorithmus für C++ ?

C

C152778

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!

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:
// 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? :confused:

Viele Grüße,
Cyraid
 
Das Problem ist deine Schleife (sowohl beim ver- als auch beim entschlüsseln)

C:
         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
C:
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:
// 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? :confused:
So wie ich es hier, am Anfang des Progamms, gemacht habe:

Code:
    for(i = 0; i <= 50; i++)
    {
      klartext[i] = ' ';
      geheimtext[i] = ' ';
    }

Beste Grüße :)
Cyraid
 
Cyraid hat gesagt.:
Meine Lösung scheint mir aber nicht sehr elegant..

es wird sich kaum eleganter lösen lassen

Cyraid hat gesagt.:
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?

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.
Außerdem kannst du mit dem [] immer noch wie von arrays gewohnt umgehen

Kurz zur verwendung

C++:
#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);
}

Cyraid hat gesagt.:
Muss ich außerdem den Array klartext und geheimtext in einer for-Schleife durchlaufen lassen, um alle Zeichen auf "leer" zu setzen? :confused:
So wie ich es hier, am Anfang des Progamms, gemacht habe:

Code:
    for(i = 0; i <= 50; i++)
    {
      klartext[i] = ' ';
      geheimtext[i] = ' ';
    }

wenn du ihn leer haben willst, ist das die einzige methode. Aber normalerweiße braucht man einen string nicht leeren
 
@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:
              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:
// 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:
  string klartext, geheimtext;

Müsste die Länge des Strings sich nicht erst durch die Eingabe des Benutzers ergeben :confused:

Viele Grüße,
Cyriad
 

Neue Beiträge

Zurück