RC4 Verschlüsselung
-
drakon schrieb:
Das kompiliert so aber nicht..

Bei einem Array musst du einen konstanten Wert angeben. Ansonsten musst du einen dynamischen Container nehmen.. (oder selbst was mit new werkeln).
||=== RC4, Release ===| C:\C++\RC4\main.cpp||In function `std::string RC4(std::string, std::string)':| C:\C++\RC4\main.cpp|44|warning: comparison between signed and unsigned integer expressions| C:\C++\RC4\main.cpp|65|warning: comparison between signed and unsigned integer expressions| C:\C++\RC4\main.cpp|68|warning: comparison between signed and unsigned integer expressions| C:\C++\RC4\main.cpp|76|warning: comparison between signed and unsigned integer expressions| ||=== Build finished: 0 errors, 4 warnings ===|bei mir schon...

MfG
@Troll: Du machst deinem Namen alle Ehre.
-
shikari* schrieb:
@Troll: Du machst deinem Namen alle Ehre.
Wenigstens kann ich programmieren.

Edit: Ernsthaft, dein Code ist kein C++. Wo kommt z. B.
stringher? Seit wann gibt es in C++ Arrays mit nichtkonstanter Größe? Seit wann kann ein Objekt NULL sein?
-
Registrierter Troll schrieb:
shikari* schrieb:
@Troll: Du machst deinem Namen alle Ehre.
Wenigstens kann ich programmieren.

int niveau; niveau = INT_MIN;edit:
Registrierter Troll schrieb:
Edit: Ernsthaft, dein Code ist kein C++. Wo kommt z. B.
stringher? Seit wann gibt es in C++ Arrays mit nichtkonstanter Größe? Seit wann kann ein Objekt NULL sein?Solange es zu keinen Fehlern kommt?
Ja, ich gebe zu, ich bin Anfänger - und?
Mehr auch nicht. Dann ist es halt kein C++. Anstatt irgendwelche dummen Kommentare abzugeben, hättest du mir auch helfen können, es anders zu lösen.
-
shikari* schrieb:
int niveau; niveau = INT_MIN;Nein nein, in C++ heißt das
int niveau = std::numeric_limits<int>::min();HTH.
-
Registrierter Troll schrieb:
shikari* schrieb:
int niveau; niveau = INT_MIN;Nein nein, in C++ heißt das
int niveau = std::numeric_limits<int>::min();HTH.
Das ist das gleiche..
-
shikari* schrieb:
solange es funktioniert?

Anstatt irgendwelche dummen Kommentare abzugeben, hättest du mir auch helfen können, es anders zu lösen.
Also entschuldige mal - du stellst hier komischen Code rein, der kein C++ ist und zeichnest ihn als "C++/CLI" aus. Ich habe keine Ahnung, wie C++/CLI aussieht und bin mal davon ausgegangen, dass du dich einfach nur im Forum geirrt hast.
Mich dann für deine eigenen Fehler zu beschimpfen ist nicht gerade niveauvoll.
-
@Registrierter Troll,
Es ist schon C++, nur äusserst hässliches.NULLfürint, statt für zeiger und 0 fürint, dannstd::stringverwenden, obwohl kein Header<string>inkludiert ist,NULLRückgabe, wodurch daraus ein Nullzeiger aufchar consterstellt wird und dann undefiniertes Verhalten auslöst und die Liste kann man wohl noch weiterführen
Hmmm, mal schauen, wenn ich heute noch Zeit finde, mache ich mal eine Mängelliste

Grüssli
-
@Dravere: Ich wär dir sehr verbunden - danke.
Ich bin eigt. Delphi und VB6 Programmierer, vielleicht kommt mein häßlicher Programmierstil daher.
MfG.
-
Was für einen Compiler verwendest du denn?
Weil ein Array kannst du normal wie Dravere sagte nur mit einem konstanten Wert initialisieren, ansonsten musst du entweder einen Container a lá std::vector nehmen oder den Speicher zur Laufzeit mit new allokieren.
-
@blub²,
Du meinst wohl eher drakon, er hat dies gesagt
@shikari*,
Also hier mal ein paar Kommentare. Ich hoffe, dass ich das meiste erwischt habe. Den Algorithmus an sich habe ich nicht korrigiert, habe nur Tipps im Code gegeben für eine bessere Struktur.#include <string> // fehlt, für std::string #include <iostream> #include <algorithm> // braucht man, falls man ein paar Dinge schöner machen möchte. // Dazu später... using namespace std; // Pass damit auf. Man sollte // using namespace nur mit äusserster Vorsicht einsetzen. // Du heblst hier die Funktion des Namensraumes aus. Wenn du // sowas nur machst, weil du zu faul bist std:: zu schreiben, // dann ist hier wirklich was verkehrt. // Herrje. Wieso ein Makro, wenn es auch eine Funktion tun würde? #define Xor(X,Y) (!!(X) ^ !!(Y)) // Makros sind sehr böse, da hinter dem Makro nur ein dummer // Textersetzungsmechanismus steckt. Makrocode kümmert sich einen // Scheiss um C++ Quellcode. Dadurch können sehr seltsame Fehler // entstehen. Makros werden vor allem in C als Ersatz für die Templates // in C++ benutzt. Oder vielleicht so formuliert, damit kein C'ler wütend wird: // Viele Makros, welche in C eingesetzt werden, können in C++ durch // Templates ersetzt werden. string RC4(string text, string password); int main() { // Geben wir dem Code doch etwas Platz ;) // string sText, sPassword, sReturn; // Man muss nicht immer alle Variablen ganz oben deklarieren. // Das galt nur bei den alten C Standards, in C++ war es nie der Fall. // Wegen der Übersichtlichkeit deklariert man die Variablen // heutzutage dort, wo man sie auch gleich als erstes braucht. cout << "Text:" << endl; string sText; cin >> sText; // Was passiert bei falscher Eingabe? // Zum Beispiel statt eines Wortes, mehrere. cout << "Password:" << endl; string sPassowrd; cin >> sPassword; // Was passiert bei falscher Eingabe? string sReturn = RC4(sText, sPassword); cout << sText.at(5) << endl; // Debug und je nach dem löst es eine Exception aus. cout << sReturn; return 0; }string RC4(string const& text, string const& password) { // Die Referenz auf ein konstantes Objekt vermeidet unnötige // Kopien. Vor allem bei komplexen und grosse Objekten, // sollte man statt einer Kopie eine Referenz auf ein konstantes // Objekt übergeben. Ausser man benötigt wirklich eine Kopie ;) // Bei fundamentalen Datentypen, bzw. kleinen Datentypen, // sollte man dagegen immer eine Kopie nehmen, da die Kopie // dann besser ist, bzw. die Referenz mehr Nachteile hat. int RB[255]; // Der Name sagt nichts. long x, y, z; // Die Namen sagen nichts. unsigned char key[255]; //unsigned char ByteArray[text.length()]; // Kein C++ Standard. Unter GCC geht es wahrscheinlich, // da GCC eine entsprechende Erweiterung unterstütz, // kommend aus C99. Aber wie gesagt, ist nicht Standard // kompatibel. // In C++ solltest du wohl sowas machen: std::vector<unsigned char> ByteArray(text.length()); // Dafür brauchst du aber den Header <vector> // unsigned char Temp; <- wird gar nicht mehr benötigt. string RC4; // Wieder gilt, dass man nicht alle Variablen ganz oben deklarieren muss. // Ich bin jetzt aber zu faul, diese auch runterzuschieben. Du sollst ja eigentlich // den Code umschreiben und verbessern, nicht ich :) cout << "1" << endl; // Debug if(text.length() == 0) { return NULL; // NULL ist ein Makro, welches durch 0 ersetzt wird. // Dadurch wird ein std::string(0) erstellt. // Was eigentlich ein std::string((char const*)0); ist. // Was schlussendlich undefiniert ist. // Korrekt wäre hier: // return ""; // oder // return std::string(); // oder // return RC4; // RC4 ist hier ja ein leerer std::string. } else if(password.length() == 0) { return NULL; // Siehe oben. } cout<< "1" << endl; // Debug for(int i = 0; i < 255; i++) { key[i] = password.at(i); // Was passiert wenn password wenig als 255 Zeichen hat? } // Eine Exception kommt geflogen ... la la la la la laaaaa // Und was ist, wenn password mehr Zeichen hat? Also irgendwas stimmt in diesem Algo nicht ;) // Auch könnte man diese for-Schleife mit einem std::copy verkürzen und lesbarer machen. // Ein Beispiel wie man std::copy aus dem Header <algorithm> verwendet, kommt später. cout<< "1" << endl; for(int i = 0; i < 255; i++) { RB[i] = i; } cout <<"1" << endl; // Debug x = 0; y = 0; z = 0; for(/*x = 0*/; x < 255; x++) { // schon wieder x = 0? Ist doch schon 0! // Oje, sehr übersichtlicher Code folgt. Vor allem kombiniert mit den // unleserlichen Variablennamen. // Hier wäre es wohl sinnvoll Dinge in Funktionen auszulagern. // Oder zumindest mit Zwischenresultaten zu arbeiten. y = ((y + RB[x] + key[x % password.length()]) % 256); // Auch für das nächste wäre eine Funktion was nettes. Es gibt // sogar bereits eine in der Standardbibliothek. Dafür muss // aber der Header <algorithm> eingebunden werden. /* Temp = RB[x]; RB[y] = RB[y]; RB[y] = Temp; */ std::swap(RB[y], RB[x]); // Ist deutlich deutlich lesbarer so eine Funktion, nicht? } x = 0; y = 0; z = 0; cout<< "1" << endl; // Debug // Das folgende kann man auch vereinfachen: /*for(int i = 0; i < text.length(); i++) { ByteArray[i] = text.at(i); } */ std::copy(text.begin(), text.end(), ByteArray.begin()); // Dafür ist der Header <algorithm> nötig. for(/*x = 0*/; x < text.length(); x++) { // Wieder setzt du x = 0, obwohl x schon 0 ist :) // Wieder sehr übersichtlicher Code. Immerhin mit ein paar Zwischenergebnissen. // Aber durch die schlechten Namen... y = (y + 1) % 256; z = (z + RB[y]) % 256; // Kann man wieder kürzen dank swap aus <algorithm> /* Temp = RB[y]; RB[y] = RB[z]; RB[z] = Temp; */ std::swap(RB[y], RB[x]); // Tjo und das ist auch nicht gerade übersichtlich und // der Übersichtlichkeit hilft das Makro nicht. Auch stimmt // der Name nicht so wirklich. Es ist kein reines XOR. ByteArray[x] = (Xor (ByteArray[x], (RB[RB[y] + RB[z]] % 256))); } /* for(int i = 0; i < text.length(); i++) { RC4 += ByteArray[i]; } */ // Kann man wieder kürzen: std::copy(ByteArray.begin(), ByteArray.end(), RC4.begin()); // Wieso arbeitest du allerdings nicht direkt auf dem RC4 Objekt? // Könntest am Anfang statt: // std::vector<unsigned char> ByteArray(text.length()); // std::string RC4; // Sowas machen: // std::string RC4 = text; // So würde auch die erste Kopie von text nach ByteArray wegfallen. cout <<"1" << endl; // Debug return RC4; }Wenn man die Korrekturen angewendet hat, könnte man wahrscheinlich nochmals drüber gehen

Ein paar allgemeine Sachen:
- Verwende die Standardbibliothek. Gerade für Container und Algorithmen ist sie extrem praktisch. Eine fast vollständige Referenz findest du hier:
http://www.cplusplus.com/reference/
- Verzichte auf Makros. Daher verwende lieber auch kein INT_MIN, sondern nehme das std::numeric_limits<int>::min(). Vielleicht ein wenig übertrieben, aber gerade als Anfänger, sollte man sich manchmal ganz klare Grenzen machen. Später kann man diese immer noch lockern, verschärfen ist aber immer problematisch.
- Probier nicht so lange aus, bis etwas kompiliert. Sondern informier dich darüber und wende die Sache so an, wie man sie anwenden muss. Der Kompiler kompiliert noch viel, was nicht korrekt ist. In C und C++ gibt es das "undefinierte Verhalten" (auch UB abgekürzt für Undefined Behavior). Es ist eine korrekte Syntax, der Kompiler lässt es somit durch, aber das Resultat ist undefiniert. Daher sollte man sich nicht zu sehr darauf verlassen, dass etwas korrekt ist, nur weil der Kompiler es aktzeptiert
Grüssli
PS: LoL, der Beitrag wurde so lang, dass es zu Problemen mit dem Forum kam
