Frage zu einfachem Verschlüsselungslgorithmus
-
bwbg schrieb:
"Kryptische Hex-Arithmetik" (gibt es Hex-Arithmetik überhaupt?) sind noch Altlasten, die ich nach meiner kurzen "Assembler-Exkursion" mit mir herumtrage (kam direkt nach BASIC). now replaced
Mit "Hex-Arithmetik" meinte ich die Sammlung an Hex-Zahlen, mit denen du dein Text-Zeichen verrechnest. Und 100% portabel bist du damit auch nicht (auch wenn jeder moderne Compiler damit arbeitet, schreibt der C++ Standard keineswegs vor, daß char im ASCII-Zeichensatz interpretiert wird*)
* Und es gibt auch Zeichensätze, die inkompatibel zu ASCII sind, z.B. EBCDIC (wobei bei dieser Codierung nichtmal die "klassische" char-Arithmetik funktionieren würde)
-
Damit ist nun auch der letzte Versuch der Rechtfertigung zu nichte gemacht...
Benutzt die Zeichenklassifikations-Funktionen!
OT: Aber die Erlösung ist nahe. Um die vielen bösartigen Zeichenkodierungen zu vertilgen wurde in dunklen Labors das Unicode-Monster gezüchtet, welches mit diversen Fangarmen (UTF-8 bis UTF-x, usw.) nach ahnungslosen String-Implementationen jagt...
-
bwbg schrieb:
OT: Aber die Erlösung ist nahe. Um die vielen bösartigen Zeichenkodierungen zu vertilgen ... UTF-8 bis UTF-x...
Womit wir weiterhin als Programmierer mit verschiedene Zeichenkodierungen zu kämpfen haben. Es gibt leider nicht EIN Unicode-System sondern mehrere.
cu André
-
Also ich habe jetzt mit Hilfe eurer Beiträge und Codes ein Programm zusammengebastelt, das so läuft wie ich es haben möchte.
Hier mal der Source-Code:
#include <iostream> #include <string> using namespace std; void verschluessele(ostream&, const string&); int main() { string nachricht; cin >> nachricht; verschluessele(cout, nachricht); return 0; } void verschluessele(ostream& out, const string& str) { string::const_iterator iter = str.begin(); for( ; iter != str.end(); iter++) { char c = *iter; if (64 < c && c < 90) cout << static_cast<int>(c-64) << ", "; else if (96 < c && c < 123) cout << static_cast<int>(c-70) << ", "; else cout << "?"; } cout << endl; }Ich würde Interesse halber gerne wissen, ob man das noch weiter optimieren könnte, denn ich möchte mir natürlich einen möglichst guten Programmierstil angewöhnen.
Aber bis hierhin schon mal vielen Dank für eure kompetente Hilfe

-
Generell sieht dein Code jetzt schon viel mehr nach C++ aus, als es dein erster Versuch war.
Du solltest jetzt nur noch die Anmerkung von CStoll bzgl. der Zeichenkonstanten umsetzen ('A' statt 65, etc.)
und möglichst die Einrückung (bei den if-Anweisungen) verbessern (um es leserlicher zu gestalten):if ('A' <= c && c <= 'Z') // besser wäre sogar: isupper(c) cout << static_cast<int>(c-'A'+1) << ", ";Ich gehe jetzt mal vom ASCII-Zeichensatz aus -)
-
Danke für die Antwort.
Ich musste gerade erstmal ein bisschen suchen, wie man isupper/islower syntaktisch richtig verwendet, da ich die Funktionen noch nie benutzt habe, aber jetzt hat´s funktioniert. Hier mal der Code:
#include <iostream> #include <string> #include <cctype> using namespace std; void verschluessele(ostream&, const string&); int main() { string nachricht; cin >> nachricht; verschluessele(cout, nachricht); return 0; } void verschluessele(ostream& out, const string& str) { string::const_iterator iter = str.begin(); for( ; iter != str.end(); iter++) { char c = *iter; if (isupper(c)) cout << static_cast<int>(c-64) << ", "; else if (islower(c)) cout << static_cast<int>(c-70) << ", "; else cout << "?, "; } cout << endl; }Falls noch jemand eine Optimierungsidee hat, bitte melden.
Vielen Dank
jawo3
-
#include <iostream> #include <string> #include <cctype> void verschluessele(std::ostream&, const std::string&); int main() { std::string nachricht; std::cin >> nachricht; verschluessele(std::cout, nachricht); return 0; } void verschluessele(std::ostream& out, const std::string& str) { for(std::string::const_iterator iter = str.begin(); iter != str.end(); ++iter) { const char c = *iter; if (isupper(c)) { out << static_cast<int>(c - 'A' + 1) << ", "; } else if (islower(c)) { out << static_cast<int>(c - 'D') << ", "; } else { out << "?, "; } } out << "\n"; }Habs aber an meinen Programmierstyle angepasst

Viele Grüße,
PatrickEdit: Ja, Ja... Mir ist eben noch was eingefallen

-
Ich habe mir mal deinen Code angeschaut und da sind mir folgende Frage in den Sinn gekommen:
Hat es irgendwelche Vorteile/Nachteile, wenn man/ wenn man nicht den "namespace std" benutzt, sondern immer ein std:: vor die einzelnen Funktionen schreibt?
Was ist der Unterschied zwischen "cout" und "out"?
-
jawo3 schrieb:
Hat es irgendwelche Vorteile/Nachteile, wenn man/ wenn man nicht den "namespace std" benutzt, sondern immer ein std:: vor die einzelnen Funktionen schreibt?
Wie gesagt: Ich habe den Code meinem eigenen Programmierstyle angepasst. Und meiner Meinung nach gibt es namespaces nicht umsonst. Ich habe mir also angwöhnt immer std:: zu schreiben

jawo3 schrieb:
Was ist der Unterschied zwischen "cout" und "out"?
Du hast immer geschrieben:
verschluessele([b]std::cout[/b], nachricht);Und ich bin davon ausgegangen, dass du in der Funktion out mit cout verwechselt hast und habe das deswegen angepasst, so das der Parameter auch genutzt wird wie es vermutlich gewollt war

Viele Grüße,
Patrick
-
Bzgl. der Verwendung des 'namespace std' hat jeder Programmierer seine eigene Schreibweise. In Header-Dateien solltest du aber NIEMALS "using namespace std;" schreiben (da du damit die Namensbereiche aushebelst und wieder alle Namen global gemacht werden).
In Source-Dateien kannst du auch alternativ einzelne Namen am Anfang benennen, um sie dann ohne 'std::' schreiben zu können:using std::string; using std::cout; // ...Eine weitere Alternative besteht dadrin, "using namespace std;" nur innerhalb von Funktionen zu verwenden:
void printMyName() { using namespace std; string s("Hallo"); cout << s << "Th!"; }Und du hast bei dir zwar 'out' als Parameter übergeben, aber nicht verwendet (hatte ich vorhin gar nicht bemerkt), sondern immer auf die Konsole ausgegeben.
Du könntest z.B. alternativ die Daten mithilfe eine ofstream-Objekts z.B. auch in eine Datei schreiben:ofstream of("Test.txt"); verschluessele(of, nachricht);
-
Okay, vielen Dank.
-
und ganz generell: bei switch-case auch immer
break;nach jedem block einfügen. sonst könnte die verschlüsselung sicherlich spassiger werden, als angedacht
-
Wird Switch nicht automatisch beendet wenn ein case eingetreten ist?
-
Nein.
-
Kommt drauf an, was du mit "beendet" meinst - der switch sucht die erste case-Marke, die zum Wert passt, und läuft von dort bis zum Blockende:
int i=1; switch(i) { case 0: cout<<0; case 1: cout<<1; case 2: cout<<2; default:cout<<"unbekannt"; }Die Ausgabe davon ist "12unbekannt"
-
Achso okay.
Jetzt habe ich aber ein neues Problem:
Ich würde gerne versuchen, ein Programm zuschreibn, was meine Verschlüsselung rückgängig macht.
Es wird also eine Eingabe dieser Form erwartet z.B. 23, 12, 1, 1, 3, 5
und daraus soll das entsprechende Wort ausgegeben werden.
Mit meinem derzeitigen Programm ist das nicht möglich, da:
1. ich nicht weiß wie man zwei Werte gleichzeitig überprüfen kann (also z.B 22 würde normalerweise als 2 und 2 behandelt werden)
2. ich nicht weiß wie man den automatischen Abbruch umgeht, wenn ein eingegebenes Leerzeichen erreicht wird.
Vielleicht könntet ihr mir einige Tipps oder Informationen zu nötigen Funktionen geben, mit denen ich ein solches Programm erstellen kann...
Vielen Dank
jawo3