Hilfe: Caesar Verschlüssung in C++



  • Hallo,

    ich benötigte Hilfe. ich habe mein Programm soweit fertig, jedoch habe ich ein Problem. Und zwar geht er, wenn er > Z ist immer weiter, dabei soll er ja eigentlich bei A wieder starten. Das Problem habe ich ebenfalls, wenn ich um 55 verschiebe, dann endet er bei den Sonderzeichen, dabei müsste das ergebnis eigentlich innerhalb von A bis Z sein.

    #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;
    
    	for (int i = 0; i <= text.length(); i++) {
    		geheim += text[i] + 2;
    		if (geheim[i] > 'z') {
    			geheim[i] -= 26;
    		}
    	}
    
    	cout << geheim << endl;
    	system("PAUSE");
    }
    


  • Der Computer kennt kein Alphabet so wie wir es kennen.
    Schau dir mal die ANSI Tabelle an, nach dem Prinzip musst du dich richten.



  • SvenJungwird schrieb:

    Und zwar geht er, wenn er > Z ist immer weiter, dabei soll er ja eigentlich bei A wieder starten.

    Wer ist eigentlich "er"? 😃



  • Hallo,

    Genau die ascii Tabelle habe ich mir bereirs angeschaut. Den string muss ich in char umwandeln. Aber ich komme dennoch nicht weiter, denn wenn ich a plus 55 eingebe, dann weiß ich nicht wie ich das abfangen soll.



  • Aaaalso ...
    zuerst mal ist Deine Schleife falsch:

    for (int i = 0; i <= text.length(); i++) {
    

    sollte

    for (int i = 0; i < text.length(); i++) {
    

    sein.

    Dann ... wenn Du um mehr als 26 verschiebst, reicht es natürlich nicht, nur einmal 26 zu subtrahieren.

    Und schlussendlich besteht der string - zumindest auf meinem System - nicht aus unsigned char, sondern aus signed char. Dh. sobald Du mit Deiner Rechnerei über 127 kommst, sind die Werte in geheim[i] negativ.
    Du musst sie also casten:

    #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;
    
        for (int i = 0; i < text.length(); i++) {
            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;
            }
        }
    
        cout << geheim << endl;
    
    }
    


  • Mhm ... ganz so einfach ist es doch nicht. Aber - da Du ja in dem Bereich 'a' - 'z' bleiben möchtest - es lohnt sich nicht, um mehr als 25 zu verschieben. Deshalb vielleicht:

    cin >> v;
        v %= 26;
    

    und dann wieder:

    geheim[i] = static_cast<unsigned>(geheim[i]) - 26;
    


  • m_diff ist der Verschiebefaktor.

    // A = 65, Z = 90, a = 97, z = 122
    unsigned char CSimpleCryptDlg::EncryptChar( int ch )
    {
    	int ret, diff;
    	if( ch >= 97 && ch <= 122 )
    	{
    		ret = ch + m_diff;
    		if( ret < 97 )
    		{
    			diff = 97 - ret;
    			ret = 123 - diff;
    		}
    		else if( ret > 122 )
    		{
    			diff = ret - 123;
    			ret = 97 + diff;
    		}
    		return( static_cast<unsigned char> (ret) );
    	}
    	else if( ch >= 65 && ch <= 90 )
    	{
    		ret = ch + m_diff;
    		if( ret < 65 )
    		{
    			diff = 65 - ret;
    			ret = 91 - diff;
    		}
    		else if( ret > 90 )
    		{
    			diff = ret - 91;
    			ret = 65 + diff;
    		}
    		return( static_cast<unsigned char> (ret) );
    	}
    	else
    		return( static_cast<unsigned char> (ch) );
    }
    


  • Hallo,

    die Eingabe ist String, wie bekomme ich den String bzw wie caste ich den String in ein Char?



  • Ähhh ... ich habs Dir doch weiter oben aufgeschrieben!?



  • SvenJungwird schrieb:

    Hallo,

    die Eingabe ist String, wie bekomme ich den String bzw wie caste ich den String in ein Char?

    Ein string kann nicht zu einem char gecastet werden, weil ein string eine Reihe von chars ist.
    Ansonsten habe ich dir doch schon ein komplettes Programm gepostet, das von -25 bis +25 für alle relevanten Zeichen funktioniert.
    Es steht auch ganz deutlich da:

    EncryptChar( int ch )
    

    Lese und lerne.



  • 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 ?


Anmelden zum Antworten