Caesar cipher oop



  • static_cast<int>(temptext[i])
    

    ???

    tempascii = 65 + (tempascii - 91);
    

    ?????

    warum nicht inplace ver- und entschlüsseln?

    std::string Caesar::decode(const std::string &text,int key)
    {
        return encode(text,-key);
    }
    


  • UUUOOPPPSSS hab ich vergessen ^^



  • Er will das Caesarverschlüsselungsverfahren benutzen. Also müssen erstmal ALLE Buchstaben groß gesetzt werden.

    pampy schrieb:

    c = (c - 'A' +26 + off) % 26 + 'Ä';
    

    Versteh ich nicht, wieso + Ä ? Wenn c == 'C' ist, wäre c laut der ASCII Tabelle 67, A = 65, Ä = 196 und off wäre beim encoden -3.

    (67 - 65 + 26 + -3) % 26 + 196 = 221

    (67 - 65 + 26 + -3) = 25 da kann man nicht % 26 machen, da es kein Rest geben wird.

    Übergebe ich den String nun nochmal und benutze die Decodierung, wird also 221 genutzt. Gleiche Rechung nur mit +3 statt -3. Somit wird dann 224 zurückgegeben, kein gültiger Buchstabe.

    pampy schrieb:

    else if(c >= 'a' && c <= 'z')
                text[i] = c;
    

    Also wenn ich den String übergebe "dzafwef", wird beim ersten Durchlauf der for-Schleife das d genommen. d ist zwischen a und z, wird angenommen. text[0] = "d". Durch text[i] = c, c entspricht im ersten Durchlauf "d", wird text[0] einfach wieder auf d gesetzt? Bei einem String von nur kleinen Buchstaben wird der String also nicht verändert.

    Selbst wenn deine Formel stimmen würde, solltest du wissen, dass Caesar nicht solche ASCII Zeichen wie unser Computer hatte. Also wenn du Y nimmst und um 3 Stellen verändern willst, gehst du über Z (1 Stelle verbraucht), musst dann wieder zu A und dann zu B.

    Hatte ich nun irgendwas falsch zu bemängeln oder gar falsch gesagt, wird doch bitte konstruktive Kritik geschrieben 😉



  • habs hinbekommen, danke fuer eure Antworten!

    Super Forum 👍



  • Also manchmal ist OOP-Fanatismus Nonsens, dies ist ein perfektes Beispiel dafür.

    So gehts viel leichter, schlanker und schneller:

    #include <stdio.h>
    #include <string.h>
    
    inline char rot13 (char c)
    { return (~c - 1 / (~((c = ~c) | 32) / 13 * 2 - 11) * 13); } 
    
    int main (void)
    {
        char buffer[] = "hallo, caeser rocks!";
        size_t length = strlen (buffer);
    
        // orginal
        printf ("orginal: %s\n", buffer);
    
        // encodieren
        for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i);
        printf ("encoded: %s\n", buffer);
    
        // decodieren
        for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i);
        printf ("decoded: %s\n", buffer);
    }
    


  • unsigned long schrieb:

    Also manchmal ist OOP-Fanatismus Nonsens, dies ist ein perfektes Beispiel dafür.

    So gehts viel leichter, schlanker und schneller:

    #include <stdio.h>
    #include <string.h>
    
    inline char rot13 (char c)
    { return (~c - 1 / (~((c = ~c) | 32) / 13 * 2 - 11) * 13); } 
    
    int main (void)
    {
        char buffer[] = "hallo, caeser rocks!";
        size_t length = strlen (buffer);
    
        // orginal
        printf ("orginal: %s\n", buffer);
    
        // encodieren
        for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i);
        printf ("encoded: %s\n", buffer);
    
        // decodieren
        for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i);
        printf ("decoded: %s\n", buffer);
    }
    

    Sind dir die Newlines ausgegangen? Hier hast du zwei:

    
    


  • Großzügiger Spender schrieb:

    unsigned long schrieb:

    Also manchmal ist OOP-Fanatismus Nonsens, dies ist ein perfektes Beispiel dafür.

    So gehts viel leichter, schlanker und schneller:

    #include <stdio.h>
    #include <string.h>
    
    inline char rot13 (char c)
    { return (~c - 1 / (~((c = ~c) | 32) / 13 * 2 - 11) * 13); } 
    
    int main (void)
    {
        char buffer[] = "hallo, caeser rocks!";
        size_t length = strlen (buffer);
    
        // orginal
        printf ("orginal: %s\n", buffer);
    
        // encodieren
        for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i);
        printf ("encoded: %s\n", buffer);
    
        // decodieren
        for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i);
        printf ("decoded: %s\n", buffer);
    }
    

    Sind dir die Newlines ausgegangen? Hier hast du zwei:

    
    

    Args Marc++us hat sie geklaut. Hier hast du ein Programm, dass dir bei jedem Aufruf zwei erzeugt, aber verrat es keinem!

    #include <iostream>
    
    int main()
    {
       std::cout << "\n\n";
    }
    


  • @Großzügiger Spender:
    auto equals banane?



  • unsigned long schrieb:

    Also manchmal ist OOP-Fanatismus Nonsens, dies ist ein perfektes Beispiel dafür.

    So gehts viel leichter, schlanker und schneller:

    #include <stdio.h>
    #include <string.h>
    
    inline char rot13 (char c)
    { return (~c - 1 / (~((c = ~c) | 32) / 13 * 2 - 11) * 13); } 
    
    int main (void)
    {
        char buffer[] = "hallo, caeser rocks!";
        size_t length = strlen (buffer);
    
        // orginal
        printf ("orginal: %s\n", buffer);
    
        // encodieren
        for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i);
        printf ("encoded: %s\n", buffer);
    
        // decodieren
        for (size_t i = 0; i < length; buffer[i] = rot13 (buffer[i]), ++i);
        printf ("decoded: %s\n", buffer);
    }
    

    hey mann!111 dat is kein c++ es hat keine classen!!111 java is besser.



  • Nö F# ist besser 🙂



  • unsigned long schrieb:

    Also manchmal ist OOP-Fanatismus Nonsens, dies ist ein perfektes Beispiel dafür....

    Habe ich auch sofort gedacht ... schon die Überschrift ist ein Widerspruch in sich.

    Was kommt als nächstes: "Freie-Funktionen-Klasse"? 😉

    Mal im Ernst: Je nachdem, was geübt werden soll:
    a) Caesar-Chiffre => freie Funktion (wenn ich auch unsigned longs obfuscated code nicht als Beispiel nehmen würde)
    b) OOP => Andere Aufgabe.

    Gruß,

    Simon2.



  • unsigned long schrieb:

    Also manchmal ist OOP-Fanatismus Nonsens, dies ist ein perfektes Beispiel dafür.

    So gehts viel leichter, schlanker und schneller:

    #include <stdio.h>
    #include <string.h>
    
    inline char rot13 (char c)
    { return (~c - 1 / (~((c = ~c) | 32) / 13 * 2 - 11) * 13); } 
    
    int main (void)
    {
        char buffer[] = "hallo, caeser rocks!";
        size_t length = strlen (buffer);
    
        // orginal
        printf ("orginal: %s\n", buffer);
    
        // encodieren
        for (size_t j = 0; i < length; buffer[j] = rot13 (buffer[j]), ++j);
        printf ("encoded: %s\n", buffer);
    
        // decodieren
        for (size_t j = 0; i < length; buffer[j] = rot13 (buffer[j]), ++j);
        printf ("decoded: %s\n", buffer);
    }
    

    Wow das Programm funktioniert richtig gut ...
    Ironie off
    Die codierung, sowie die decodierung geht überhaupt nicht! Es soll alles ins große geschrieben und wenn man Y um 3 Stellen nach rechts verschieben soll, muss B als Endergebnis rauskommen.
    Das macht dein Programm nicht. Hast du es etwa nicht getestet ?...



  • *hust*

    da oben steht "rot13" nicht "rot3". Der Code sollte nur ein Denkanstoß dafür sein, dass es auch ohne OOP sogar besser (schneller, schlanker - einfach besser) geht.

    Noch was in eigener Sache:

    Dazu solltest du es unterlassen verfälschten Code zu posten. Stichwort Zeile 16 und 20 in deinem Post und meinem Post. Mein Code geht, dein geposteter nicht, da du absichtlich "i" und "j" in beiden Zeilen verschoben hast. Daher ist es unterste Schublade hier mit "Ironie" anzutanzen.

    Also kusch, kusch, ab in die Ecke und schämen.


  • Administrator

    @unsigned long,
    Du hast durchaus zum Teil recht, wenn du das ganze aber doch bitte noch in C++ machen würdest, dann sähe es noch ein wenig besser aus:

    #include <string>
    #include <iostream>
    #include <algorithm>
    
    char rot13(char c)
    {
    	return (~c - 1 / (~((c = ~c) | 32) / 13 * 2 - 11) * 13);
    }
    
    int main()
    { 
    	std::string buffer = "hallo, caeser rocks!";
    
    	// originial
    	std::cout << "Original: " << buffer << std::endl;
    
    	// encoding
    	std::transform(buffer.begin(), buffer.end(), buffer.begin(), &rot13);
    	std::cout << "Encoded:  " << buffer << std::endl;
    
    	// decoding 
    	std::transform(buffer.begin(), buffer.end(), buffer.begin(), &rot13);
    	std::cout << "Decoded:  " << buffer << std::endl;
    
    	return 0;
    }
    

    Wieso sage ich "zum Teil"? Wenn du mal den Code von pampy genauer angeschaut hättest, dann hättest du eine Offset Variable entdeckt. Daher muss hier ein Objekt eingeführt werden.

    Allerdings hätte ich es persönlich über einen Funktor gemacht, also sowas:

    // Code von oben, statt der rot13 Funktion, eher sowas:
    struct Encoding
    {
      int m_offset;
    
      Encoding(int offset)
        : m_offset(offset)
      {
      }
    
      char operator ()(char c)
      {
        // ... Kodierung hier hin ... //
      }
    }
    
    // In der main dann:
    std::transform(buffer.begin(), buffer.end(), buffer.begin(), Encoding(13));
    
    // ...
    

    Aber ich würde sowas schon eher als fortgeschrittene Programmierung ansehen. Einem Anfänger traue ich jedenfalls so ein Vorgehen nicht einfach so zu. Schon nur wegen der Operatorüberladung.

    Grüssli



  • Dravere schrieb:

    ...Daher muss hier ein Objekt eingeführt werden....

    Naja ... aber nur, wenn man das (schicke und sprechende) transform() nutzen will.
    Mit einer simplen handkodierten Schleife hätte es eine einfache Funktion auch getan.

    Gruß,

    Simon2.



  • Das mit der Offset-Variable stimmt, das habe ich überlesen.

    Was mir jedoch Kopfzerbrechen bereitet ist hierfür die STL zu benutzen. Keine Frage, STL ist ein feines Teil, aber gerade für sowas denke ich, ist es eher als ob man eine Neutronenbombe auf eine Ameise wirft. Ich denke nicht, das hier die Anwendung der STL irgendeinen Vorteil birgt, eher Abzüge in Performance, Overhead usw. mit sich führt.

    Aber da streitet natürlich die Welt drum und einen "C/C++-Mix"- vs. "pure C++"-Flamewar möchte ich sicherlich nicht anzetteln.

    Ich hab nur gezeigt wie ich eine einfache Rot13 implementieren würde, ohne viel Schnick Schnack. Natürlich kann man hier auch richtig tiefe Vererbung ansetzen (Klassen für a-/symmetrische Verschlüsselung, Einwegverschlüsselung, usw.), mit Namespaces und co. Aber der Aufwand/Nutzen-Faktor würde meines Erachtens hier nicht sehr berauschend sein.



  • @unsigned long
    Was heisst verfälschten Code?
    Zeig mir doch mal bitte wie mein ein Array benutzt wie z.B. "test []" und in dem Index eine Variable angibt, die "i" heisst und gleichzeitig so eine Schrift benutzt "Test" 🙄
    Deswegen habe ich "i" durch "j" benutzt, damit ich das benutzen kann...
    Und außerdem verändert das wohl nicht das Geringste...



  • for (size_t j = 0; i < length; buffer[j] = rot13 (buffer[j]), ++j);
    

    Wenn du so einen crap baust, brauchste nicht zu heulen, das nichts läuft.

    Der Code von mir funktioniert und das einwandfrei. Aber bitte. Laber du mal ruhig, wir haben hier gerade eine ganz andere Thematik.


  • Administrator

    @Simon2,
    Ich habe noch überlegt, ob ich das "muss" abschwächen sollte. Aber dachte: "Ach dagegen wird sicher niemand einen Einwand haben."
    War wohl falsch gedacht 🙂
    Aber recht hast du natürlich schon 😉

    unsigned long schrieb:

    Was mir jedoch Kopfzerbrechen bereitet ist hierfür die STL zu benutzen. Keine Frage, STL ist ein feines Teil, aber gerade für sowas denke ich, ist es eher als ob man eine Neutronenbombe auf eine Ameise wirft. Ich denke nicht, das hier die Anwendung der STL irgendeinen Vorteil birgt, eher Abzüge in Performance, Overhead usw. mit sich führt.

    Die STL-Algorithmen werden meistens völlig wegoptimiert. Daher ist dein Bedenken hier grundlos. Ein std::transform ist intern auch nichts anderes als eine Schleife. Was man schlussendlich wirklich gewinnt ist Übersicht. Ein std::transform lässt sich deutlich besser lesen als eine for -Schleife.

    Was womöglich gewisse Performanceeinbussen bringen könnte, ist die Verwendung des std::string als Puffer. Hier werden sehr wahrscheinlich beim Iterieren zusätzliche Bereichsprüfungen durchgeführt. Aber man kann den std::string natürlich ohne Probleme auch wieder durch deinen char Puffer ersetzen. Die Verwendung von std::transform kann immer noch genutzt werden. Ich könnte mir vorstellen, dass man dann sogar einen Performancegewinn erzielen könnte, da man gleich mit Zeigerarithmetik arbeitet. Allerdings ist das nur eine Spekulation von meiner Seite 😉
    Ich habe einen std::string genutzt, weil ich den Hintergedanken hatte, dass man mit dem String womöglich mehr machen möchte, als nur kodieren und dekodieren. Wahrscheinlich möchte man zuerst etwas vom Benutzer einlesen lassen oder ähnliches und da erleichtert einem die Verwendung des std::string einiges.

    Gespräche über die Performance sollte man eigentlich sowieso besser zusammen mit einem Profiler machen. Sonst kann man eigentlich immer nur spekulieren. Allerdings wurde schon mehrmals bewiesen, dass STL Algorithmen nicht langsamer sind als normale eigene Schleifen, bzw. kein Nachteil durch diese entsteht.
    Zudem ist Performance ja schön und gut, aber die Übersicht sollte man bei einem Programm auch im Hinterkopf behalten. Optimieren kann man im nachhinein immer noch. Auch sollte man die Programmiersprache, welche man gewählt halt, auch benutzen. Wenn etwas besser in C geschrieben werden sollte, dann kann man natürlich die Programmiersprache wechseln. Aber ein zwanghaftes mischen von C und C++, vor allem an Stellen, wo man gar nicht so recht weiss, ob man etwas durch die Verwendung von C gewinnt, halte ich für ein schlechtes Vorgehen. Sowas führt zu unübersichtlichem und dadurch unwartbarem Code.

    Grüssli



  • Dravere schrieb:

    @Simon2,
    Ich habe noch überlegt, ob ich das "muss" abschwächen sollte. Aber dachte: "Ach dagegen wird sicher niemand einen Einwand haben."
    War wohl falsch gedacht 🙂
    Aber recht hast du natürlich schon 😉
    ...

    Tja ... wie sagte meine Deutschlehrerin immer: "Pauschalisierungen sind immer falsch!" 😉
    Und schön finde ich das schon mit dem transform() ...

    Gruß,

    Simon2.


Anmelden zum Antworten