Cäsar Verschlüsselung mit dynamischer Verschiebung
-
ja erst mal hallo alle hier , bin neu und hab gerade erst mit dem programieren begonnen das heißt ich mach ein fernstudium .
jetzt hab ich folgendes problem , ich soll ein programm zum verschlüsseln einer nachricht schreiben und der verschiebewert soll dynamisch sein . das erste zeichen soll um eine position verschoben sein , das zweite um zwei usw.
wer kann mir einen tip geben wie ich das mit den positionen regeln kann. die verschlüsselung funktioniert bereits allerdings nur mit einem festen verschiebewert.
besten dank im voraus
-
Na, mit einer einfachen Schleife:
std::string str("Hallo Welt!"); for(size_t ct(0);ct < str.length();++ct) str[ct] += circular_shift(ct);
-
hallo sone ,
erst mal danke für deine schnelle antwort , aber leider kann ich die befehle die du schreibst nicht verstehen .
ich hab mal mein prg. hier vielleicht kannst du mir sagen wies weiter geht so das auch ich das versteh.#include <iostream>
using namespace std;
void caesar();
void caesar (string kette){
int laenge , verschiebung ;
laenge = kette.length();cout<<" verschiebewert eingeben: ";
cin>>verschiebung;
for (int zaehler=0;zaehler<laenge;zaehler++)
{
cout<<static_cast<char>(kette[zaehler]+ verschiebung);
cout<<endl<<endl;
}}
int main()
{
string eingabe;
cout<<"geben sie ein Wort ein das sie verschluesseln moechten: ";
cin>>eingabe;
cout<<"sie haben: "<<eingabe<<" eingegeben"<<endl;caesar (eingabe);
return 0;
}wie gesagt ich bin absoluter anfänger , ich hab auch an eine schleife gedacht aber ich kapier irgendwie das mit der dynamic nicht . obiges prg. funktioniert eben nur mit der festen verschiebung
danke joergi
-
joergi_1 schrieb:
#include <iostream>Hier fehlt noch ein #include <string>
joergi_1 schrieb:
using namespace std; void caesar(); void caesar (string kette){ int laenge , verschiebung ; laenge = kette.length();Vermeide getrenntes Definieren und Initialisieren.
int laenge = kette.size(); // tut's auchjoergi_1 schrieb:
cout<<" verschiebewert eingeben: "; cin>>verschiebung; for (int zaehler=0;zaehler<laenge;zaehler++) { cout<<static_cast<char>(kette[zaehler]+ verschiebung); cout<<endl<<endl; }Wenn ich das richtig verstanden habe, soll dein Programm gar nicht nach der verschiebung fragen sondern als Verschiebung zaehler+1 verwenden. Du solltest das vielleicht auch die Ausgabe weglassen und stattdessen das verschlüsselte Wort zurück geben (per return und entsprechendem Rückgabetyp, also string statt void).
joergi_1 schrieb:
} int main() { string eingabe; cout<<"geben sie ein Wort ein das sie verschluesseln moechten: "; cin>>eingabe; cout<<"sie haben: "<<eingabe<<" eingegeben"<<endl; caesar (eingabe); return 0; }wie gesagt ich bin absoluter anfänger , ich hab auch an eine schleife gedacht aber ich kapier irgendwie das mit der dynamic nicht . obiges prg. funktioniert eben nur mit der festen verschiebung
danke joergiDas "dynamisch" soll einfach nur heißen, dass nicht für jedes Zeichen des Wortes dieselbe Verschiebung benutzt wird. Die Verschiebung soll also von zaehler abhängig sein.
-
Sone schrieb:
Na, mit einer einfachen Schleife: [...]
Schleifen? Pfff...
#include <cctype> #include <string> #include <iostream> #include <iterator> #include <algorithm> class caesar_t { private: int const static alphabet_length = 'z' - 'a' + 1; int key, const delta; caesar_t( int const key, bool const decrypt = false ) : key( decrypt ? -key : key ), delta( decrypt ? -1 : 1 ) { } public: static std::string caesar( std::string const &plaintext, int const key, bool const decrypt = false ) { std::string result; std::transform( plaintext.begin(), plaintext.end(), std::back_inserter( result ), caesar_t( key, decrypt ) ); return result; } std::string::value_type operator() ( std::string::value_type ch ) { ch = std::isalpha( ch ) ? ( std::isupper( ch ) ? 'A' : 'a' ) + ( std::toupper( ch ) + key ) % alphabet_length : ch; key = key % alphabet_length || !key ? key + delta : 0; return ch; } }; int main() { std::string text = "Foooooohoooobaaahaarrrr"; std::cout << "Encrypted: " << ( text = caesar_t::caesar( text, 2 ) ) << '\n'; std::cout << "Decrypted: " << caesar_t::caesar( text, 2, true ) << '\n'; }
// edit: eloganter
// edihit: kaufe noch einconst...
// edihihihididit: und noch ein paar...
// edihihihihihidihit:linecount -= 4
// edihihihihihidihihit:variablecount -= 1
-
Swordfish schrieb:
Sone schrieb:
Na, mit einer einfachen Schleife: [...]
Schleifen? Pfff...
std::transform( plaintext.begin(), plaintext.end(), std::back_inserter( encrypted ), caesar_t( key, decrypt ) );Hahaha, *LOL*
-
Ok, der Kürze wegen ...
#include <cctype> #include <string> #include <iostream> std::string caesar( std::string &str, int key, bool const decrypt = false ) { int const delta = decrypt ? -1 : 1; key = delta * key; for( std::string::iterator i = str.begin(); i != str.end(); ++i, key = key % ( 'z' - 'a' + 1 ) || !key ? key + delta : 0 ) *i = std::isalpha( *i ) ? ( std::isupper( *i ) ? 'A' : 'a' ) + ( std::toupper( *i ) + key ) % ( 'z' - 'a' + 1 ) : *i; return str; } int main() { std::string text = "Foooooohoooobaaahaarrrr"; std::cout << "Encrypted: " << caesar( text, 2 ) << '\n'; std::cout << "Decrypted: " << caesar( text, 2, true ) << '\n'; }
-
Und weil mir grad so lw. war...
#include <iostream> #include <string> #include <vector> using namespace std; class CesarChar { char _char; bool CharIsLetter() const { return (_char >= 65 && _char <= 90) || (_char >= 97 && _char <= 122); } public: CesarChar(char ch = ' ') : _char(ch){} CesarChar operator+(unsigned amount) const { amount %= 26; CesarChar temp(*this); for (unsigned i = 0; i<amount; ++i) ++temp; return temp; } CesarChar operator-(unsigned amount) const { amount %= 26; CesarChar temp(*this); for (unsigned i = 0; i<amount; ++i) --temp; return temp; } CesarChar operator-=(unsigned amount) { amount %= 26; *this = *this-amount; return *this; } CesarChar operator+=(unsigned amount) { amount %= 26; *this = *this+amount; return *this; } CesarChar operator++() { if (!CharIsLetter()) return *this; switch (_char) { case 'z': _char = 'a'; break; case 'Z': _char = 'A'; break; default: ++_char; break; } return *this; } CesarChar operator--() { if (!CharIsLetter()) return *this; switch (_char) { case 'a': _char = 'z'; break; case 'A': _char = 'z'; break; default: --_char; break; } return *this; } char ch() const {return _char;} }; class CesarString { vector<CesarChar> _string; vector<unsigned> _amounts; public: CesarString(string str = " ") : _string(str.begin(), str.end()){} void crypt(unsigned amount) { for (vector<CesarChar>::iterator it = _string.begin(); it != _string.end(); ++it) (*it) += amount; _amounts.push_back(amount); } void decrypt() { for (vector<unsigned>::iterator it = _amounts.end()-1; it != _amounts.begin()-1; --it) { for (vector<CesarChar>::iterator jt = _string.begin(); jt != _string.end(); ++jt) *jt -= *it; _amounts.pop_back(); } } void print() { for (vector<CesarChar>::iterator it = _string.begin(); it != _string.end(); ++it) std::cout << it->ch(); cout << '\n'; } }; int main() { CesarString str("test123"); str.print(); str.crypt(20); str.print(); str.crypt(28); str.print(); str.decrypt(); str.print(); }... und kritisiert nicht meinen Stil, hab ich jetzt nur so aus langeweile hingeklatscht.
-
CesarChar operator+(unsigned amount) const { amount %= 26; CesarChar temp(*this); for (unsigned i = 0; i<amount; ++i) ++temp; return temp; } CesarChar operator-(unsigned amount) const { amount %= 26; CesarChar temp(*this); for (unsigned i = 0; i<amount; ++i) --temp; return temp; }Lol. Machen die Funktionen abgesehen vom De/In-krement nicht genau dasselbe?
Das kann man doch wenigstens in eine_implFunktion auslagern...
-
Ich bin Matrix... schrieb:
... und kritisiert nicht meinen Stil, hab ich jetzt nur so aus langeweile hingeklatscht.
for (vector<unsigned>::iterator it = _amounts.end()-1; it != _amounts.begin()-1; --it)Das ist allerdings keine Stilfrage, sondern Unfug.
Da in einer vorwärtslaufenden Schleife der Itertaor jeweils unmittelbar vor dem Test auf Schleifenende inkrementiert wird, muss logischerweise in einer entsprechend rückwärts laufenden Schleife der Iterator unmittelbar nach dem Vergleich dekrementiert werden. Abgesehen davon, wird dein Iterator durch das pop_bck ungültig.for ( ; !_amounts.empty(); ) { for (vector<CesarChar>::iterator jt = _string.begin(); jt != _string.end(); ++jt) *jt -= _amounts.back(); _amounts.pop_back(); }
-
camper schrieb:
Ich bin Matrix... schrieb:
... und kritisiert nicht meinen Stil, hab ich jetzt nur so aus langeweile hingeklatscht.
for (vector<unsigned>::iterator it = _amounts.end()-1; it != _amounts.begin()-1; --it)Das ist allerdings keine Stilfrage, sondern Unfug.
Ohne irgendwie drauf zu schauen, würd ich sagen, dass geht mit
reverse_iteratoren besser.
-
Ohne irgendwie drauf zu schauen, würd ich sagen, dass geht mit reverse_iteratoren besser.
Ist mir schon klar, aber wie gesagt, ist aus reiner langeweile entstanden und da ich mich mit reverse_iterator noch nicht eingehend beschäftigt habe und kb hatte mit vollem Traffic zu googlen hab ichs gelassen^^
Abgesehen davon, wird dein Iterator durch das pop_bck ungültig.
... und wird direkt danach dekrementiert bzw. beim Ende der Schleife verworfen. Wo liegt da das Problem?
Das ist allerdings keine Stilfrage, sondern Unfug.
Da in einer vorwärtslaufenden Schleife der Itertaor jeweils unmittelbar vor dem Test auf Schleifenende inkrementiert wird, muss logischerweise in einer entsprechend rückwärts laufenden Schleife der Iterator unmittelbar nach dem Vergleich dekrementiert werden.Ja, jetzt wo ich nochmal draufguck, seh ich, das ist Unfug. Was solls, ich glaube keine der hier angebotenen Lösungsmöglichkeiten hat der TE verstanden.
wie gesagt ich bin absoluter anfänger
... weshalb er wohl nichtmal mit dem Begriff Standard-Bibliothek was anfangen können wird.
-
@krümmelkacker,
das mit der dynamic hast du richtig verstanden ,
hab das programm jetzt am laufen .
vielen dank an alle mfg joergi