Hilfe: Caesar Verschlüssung in C++



  • Hallo,

    Ok. Und wie übergebe ich das value von getline ( was an string ist) an die Funktion?



  • Du übergibst die Zeichen nacheinander in einer Schleife.



  • Soo,

    ich habe nun mal alles zusammen gefügt. Leider funktioniert es nicht.

    Muss ich eigentlich static cast verwenden?

    #include <iostream>
    #include <string>
    
    using namespace std;
    int main() {
    
    	string text;
    	int v;
    	string geheim;
    	char ch = 0;
    	int ret, diff;
    	cout << "Bitte geben Sie den zu verschluesselnden Text ein: ";
    	getline(cin, text);
    
    	cout << "Bitte geben Sie die Anzahl Verschiebepositionen ein (als positive ganze Zahl): ";
    	cin >> v;
    
    	for (int i = 0; i <= 5; i++) {
    		text[i] += ch;
    	}
    	if (ch >= 97 && ch <= 122)
    	{
    		ret = ch + v;
    		if (ret < 97)
    		{
    			diff = 97 - ret;
    			ret = 123 - diff;
    		}
    		else if (ret > 122)
    		{
    			diff = ret - 123;
    			ret = 97 + diff;
    		}
    		cout << static_cast<unsigned char> (ret);
    	}
    	else if (ch >= 65 && ch <= 90)
    	{
    		ret = ch + v;
    		if (ret < 65)
    		{
    			diff = 65 - ret;
    			ret = 91 - diff;
    		}
    		else if (ret > 90)
    		{
    			diff = ret - 91;
    			ret = 65 + diff;
    		}
    		cout << static_cast<unsigned char> (ret);
    	}
    	else
    		cout << static_cast<unsigned char> (ch);
    
    	cout << geheim << endl;
    	system("PAUSE");
    }
    


  • Du hast jetzt einfach alles zusammenkopiert, scheinbar ohne darüber nachzudenken.
    Überlege einfach mal was jede deiner Codezeilen tut. Z. Bsp die Variable ch. Was steht da drin?
    Was macht diese Schleife?

    for (int i = 0; i <= 5; i++) {
            text[i] += ch;
        }
    

    Die Variable geheim. Schreibst du da irgendwann etwas rein?
    usw.



  • Hallo,

    die Variable geheim, ist unnötig, dafür habe ich ja jetzt ret.

    Für mich ist entscheidend, dass er mir etwas ausgibt, wenn ich String to Char "konvertiere". Die ganzen If-Anweisungen vergleichen mit der ASCII Tabelle, ob der buchstabe innerhalb des Bereichs liegt.



  • Du hättest meine Funktion als Funktion benutzen sollen anstatt alles ohne Plan zusammenzukopieren.
    So wird das nix.

    Ausserdem habe ich geschrieben, daß das auch mit negativen Werten funktioniert - zum entschlüsseln.
    +25 und -25 als Grenze habe ich nur als vernünftige Werte gewählt. Was passiert den bei rot26?



  • ok



  • string.at oder sowas. Das findest du schon noch raus.

    Ach komm, ich bin heute geduldig:

    string input, output;
    for( unsigned i = 0; i < input.length(); ++i )
    	output += EncryptChar( input.at( i ) );
    


  • Hallo,

    #include <iostream>
    #include <string>
    
    using namespace std;
    int main() {
    
    	string ch;
    	int v;
    
    	int ret, diff;
    	cout << "Bitte geben Sie den zu versch[i]luesselnden Text ein: ";
    	getline(cin, ch);
    
    	cout << "Bitte geben Sie die Anzahl Versch[i]iebepositionen ein (als positive ganze Zahl): ";
    	cin >> v;
    
    	for (int i = 0; i < ch.length(); i++) {
    
    		if (ch[i] >= 97 && ch[i] <= 122)
    		{
    			ret = ch[i] + v;
    			if (ret < 97)
    			{
    				diff = 97 - ret;
    				ret = 123 - diff;
    			}
    			else if (ret > 122)
    			{
    				diff = ret - 123;
    				ret = 97 + diff;
    			}
    			cout << static_cast<unsigned char> (ret);
    		}
    		else if (ch[i] >= 65 && ch[i] <= 90)
    		{
    			ret = ch[i] + v;
    			if (ret < 65)
    			{
    				diff = 65 - ret;
    				ret = 91 - diff;
    			}
    			else if (ret > 90)
    			{
    				diff = ret - 91;
    				ret = 65 + diff;
    			}
    			cout << static_cast<unsigned char> (ret);
    		}
    		else
    			cout << static_cast<unsigned char> (ch);
    
    	}
    
    	system("PAUSE");
    }
    

    Nun funktioniert es soweit. Aber leider kommt das falsche Ergebnis raus:
    Bitte geben Sie den zu verschluesselnden Text ein: Abc Zyx!
    Bitte geben Sie die Anzahl Verschiebepositionen ein (als positive ganze Zahl): 55
    Es kommten irgendwelche Sonderzeichen raus.

    Es sollte:

    Def Cba!
    Drücken Sie eine beliebige Taste . . .



  • Lies meine 2 letzten posts.
    Was macht es für einen Sinn in einem Alphabet mit 26 Zeichen um 55 Zeichen in der ASCII-Tabelle zu verschieben? Richtig - keinen.

    So langsam habe ich keine Lust mehr. Der Geduldsfaden ist am reissen.



  • Sinn macht es keinen. Trotzdem möchte ich es realisieren können. Hat jemand eine idee ?



  • machs doch mit nem array arr = "abcdefghijklmnopqrstuvwxyz" aus dem input-zeichen c wird dann mit index = tolower (c)-'a' der index ermittlt und mit dem verschiebewert v dann zu c2 = arr[(index+v)%26], also dem verschlüsselten zeichen.

    ^^ das entspräche dann wohl am meisten der ursprünglichen idee der verschiebe-chiffre. 🙂



  • nicht if ( geheim[i] > 'z' )
    sondern while (geheim[i] > 'z' )

    das würde schonmal besser funktionieren. Wie wurde früher die Caesar-Verschlüsselung realisiert? Richtig, mit so einer Art Drehscheibe. Die konnte man auch öfter als einmal verdrehen, das heißt eine Implementierung in c++ ohne so ein komisches "%" (Modulo!!) geht ein wenig an der ursprünglichen Idee vorbei



  • swapper schrieb:

    machs doch mit nem array arr = "abcdefghijklmnopqrstuvwxyz" aus dem input-zeichen c wird dann mit index = tolower (c)-'a' der index ermittlt und mit dem verschiebewert v dann zu c2 = arr[(index+v)%26], also dem verschlüsselten zeichen.

    Und das gleiche nochmal für Großbuchstaben?
    Dem Mann fehlt ganz offensichtlich alles an Grundlagen, dann konfrontiere ihn nicht mit dermaßen komplizierten Vorschlägen.

    Was soll denn dabei rauskommen wenn ich 'z' um 55 Positionen nach hinten verschiebe? Natürlich ein Sonderzeichen.

    Modulo ist auch keine Lösung. 😉



  • Meiner Meinung nach funktioniert sein erstes Programm!

    Er muss nur

    1. Diese komische "+2" durch "+ v" ersetzen

    2. Direkt nach dem einlesen von v
      v %= 26; ( Ohhhhh, ein Modulo, Caesar wird langsam aufhören, im Grabe zu rotieren und überlässt das lieber seiner Scheibe 😉 )
      einfügen, damit nur Buchstaben kommen.

    3. Sonderzeichen sollten vielleicht nicht mit verschlüsselt werden, ist aber Geschmackssache.

    und natürlich die falsche Schlussbedingung in der for-Schleife, aber das wurde ja schon genannt.

    Ich finde es schade, dass hier dermaßen auf dem TE herumgehackt wird. Er stellt eine einfache Frage, auf die es eine einfache Antwort gibt. Sein Programm hat eine ganz eigene "Eleganz", aber an sich ja funktional. Hier kommen dann eigene Lösungen, die mit vermutlich sehr viel Hintergrund-Wissen und jahrelanger Erfahrung erstellt wurden, und dann regt man sich auf, dass der TE damit überfordert ist...

    Deine erste Lösung war für einen Neuling sehr ordentlich, lass dir nichts anderes einreden!



  • gast12987897 schrieb:

    Ich finde es schade, dass hier dermaßen auf dem TE herumgehackt wird.

    Das habe ich nicht - im Gegenteil, ich habe ihm mehrere helfende Hände gereicht.



  • EOP schrieb:

    Und das gleiche nochmal für Großbuchstaben?

    nö, das programm macht einfach gnadenlos großbuchstaben zu kleinbuchstaben (oder umgekehrt). normalerweise ist groß oder klein dem caesar unbekannt. ziffern und satzzeichen etc. auch nicht. den ollen römern stellte sich das problem einfach nicht.



  • swapper schrieb:

    EOP schrieb:

    Und das gleiche nochmal für Großbuchstaben?

    nö, das programm macht einfach gnadenlos großbuchstaben zu kleinbuchstaben (oder umgekehrt). normalerweise ist groß oder klein dem caesar unbekannt. ziffern und satzzeichen etc. auch nicht. den ollen römern stellte sich das problem einfach nicht.

    PHP str_rot13 berücksichtigt auch GROß und klein.



  • Hallo,

    zuerst einmal danke an alle.

    Es funktioniert, bzw. geht in die richtige richtung.
    Eingabe: abc def xyz!ABC XYZ?
    Verschiebe um 3:

    Ausgabe: def ghi abc$DEF []B

    Sollte aber sein:

    def ghi abc!DEF ABC?

    ____
    2. Beispiel:
    Eingabe: Abc Zyx!
    Verschiebe um 55

    Ausgabe: Def ]ba$

    Sollte aber sein:

    Def Cba!

    Ich bin so nah am Ziel! Die Frage ist nur, wieso stehen dort sonderzeichen, obwohl ich die mit IF ausgeschlossen habe? Normalerweise sollten es buchstaben ergeben, wieso ergeben es Sonderzeichen?

    #include <iostream>
    #include <string>
    
    using namespace std;
    int main() {
    
    	string text;
    	int v;
    	string geheim;
    	cout << "Bitte geben Sie den zu verschluesselnden Text ein: ";
    	getline(cin, text);
    
    	cout << "Bitte geben Sie die Anzahl Verschiebepositionen ein (als positive ganze Zahl): ";
    	cin >> v;
    	v %= 26;
    	for (int i = 0; i < text.length(); i++) {
    
    		if(text[i] >= 65 && text[i] <= 122) {
    
    			geheim += static_cast<unsigned>(text[i]) + v;
    
    			if (static_cast<unsigned>(geheim[i]) > 'z') {
    				geheim[i] = static_cast<unsigned>(geheim[i]) - (v / 26 + 1) * 26;
    			}
    
    		}
    		else {
    			geheim += text[i];
    		}
    
    	}
    
    	cout << geheim << endl;
    	system("pause");
    
    }
    


  • EOP schrieb:

    swapper schrieb:

    EOP schrieb:

    Und das gleiche nochmal für Großbuchstaben?

    nö, das programm macht einfach gnadenlos großbuchstaben zu kleinbuchstaben (oder umgekehrt). normalerweise ist groß oder klein dem caesar unbekannt. ziffern und satzzeichen etc. auch nicht. den ollen römern stellte sich das problem einfach nicht.

    PHP str_rot13 berücksichtigt auch GROß und klein.

    um das zu erreichen, kann sich der code ja merken, ob das zeichen vorher groß war und es dann wieder groß machen. dafür ist bei rot13 der verschiebefaktor festgenagelt.

    beispiel:

    /**
     * rotate one char like cesar did. (but case preserving) ;)
     * @param c input char
     * @param v steps to rotate
     * @return rotated char (if it is a letter)
     */
    char rot (char c, int v)
    {
        static char* arr = "abcdefghijklmnopqrstuvwxyz";
        if (isalpha(c))
        {
            char low = tolower(c);
            char out = arr[(low-'a'+v)%26];
            return low == c ? out : toupper(out);
        }
        return c; // not a letter
    }
    

Anmelden zum Antworten