Char array mit anderen Char array XOR verknüpfen zur Verschlüsselung
-
*gelöst*
Hallo Forum,
wir sollen ein Programm schreiben, das ein Char Array einließt (Benutzereingabe) und danach eine weitere Array Benutzereingabe von einen Schlüssel aus beliebigen Zeichen, welcher maximal halb so groß sein darf.
Dann sollen die beiden Arrays XOR-Verknüpft werden (außer die Zeichen sind an der Stelle gleich, dann diese Stelle überspringen), der so verschlüsselte Text ausgegeben werden, danach wieder mit den selben Schlüssel entschlüsselt werden und der entschlüsselte Text (welcher ja wie der Ursprungstext sein sollte) ausgegeben werden.
Ich habe folgenden Code dazu geschrieben:
#include <conio.h> #include <stdio.h> #include <string.h> #include <string.h> #define arraygroese 100 int main() { char ursprungstext[arraygroese]; //Ursprungstext char schluessel[arraygroese/2]; //Schlüssel (maximal halb so Groß wie zu verschlüsselnder Text) char verschluesselt[arraygroese]; //verschlüsselter Text char entschluesselt[arraygroese]; //entschlüsselter Text int i,u=0,laenge=0,laengeschluessel=0; //Zählvariable, Länge Ursprungstext und Länge Schlüssel //Eingabe Satz printf("Bitte geben Sie den zu verschluesselnden Satz (maximal 100 Zeichen) ein: \n"); gets(ursprungstext); laenge=strlen(ursprungstext); //Eingabe Satz ENDE //Eingabe Schlüssel printf("\n Bitte geben Sie die Zeichen fuer die Verschluesselung ein (maximal 50): \n"); gets(schluessel); laengeschluessel=strlen(schluessel); //Eingabe Schlüssel ENDE //Verschlüsselung for(i=0;i<laengeschluessel;i++) //zählt von 0 bis Länge Schlüssel { while(ursprungstext[i]==schluessel[i]) //Überprüfung der Zeichen auf Gleichheit { verschluesselt[i]=ursprungstext[i]; //wenn die Zeichen gleich sind, wird es nicht verschlüsselt sondern einfach unverschlüsselt übertragen i++; //und beim nächsten Zeichen weitergemacht } verschluesselt[i]=ursprungstext[i]^schluessel[i]; //XOR-Verknüpfung } for(i=laengeschluessel;i<laenge;i++) //zählt von Länge des Schlüssels bis Länge Ursprungssatz (z.B. 50-99) und fängt beim Schlüssel wieder vorne an (i-laenge/2) { while(ursprungstext[i]==schluessel[u]) //zb 50-50 entspricht wieder dem ersten Element des Arrays des Schlüssels { verschluesselt[i]=ursprungstext[i]; i++; u++; if(u>laengeschluessel) u=0; } verschluesselt[i]=ursprungstext[i]^schluessel[u]; //XOR-Verknüpfung // (laenge/2) entspricht erneutes durchlaufen des Schlüssels u++; if(u>laengeschluessel) u=0; } u=0; //Verschlüsselung ENDE //Ausgabe verschlüsselter Text printf("\n Der verschluesselte Text lautet: \n"); for(i=0;i<laenge;i++) printf("%c", verschluesselt[i]); //Ausgabe verschlüsselter Text ENDE //Entschlüsselung for(i=0;i<laengeschluessel;i++) //zählt von 0 bis Schlüssellänge { while(verschluesselt[i]==schluessel[i]) { entschluesselt[i]=verschluesselt[i]; i++; } entschluesselt[i]=verschluesselt[i]^schluessel[i]; //XOR-Verknüpfung } for(i=laengeschluessel;i<laenge;i++) //zählt von Länge Schlüssel bis Länge verschlüsselter Satz { while(verschluesselt[i]==schluessel[u]) { entschluesselt[i]=verschluesselt[i]; i++; u++; if(u>laengeschluessel) u=0; } entschluesselt[i]=verschluesselt[i]^schluessel[u]; //XOR-Verknüpfung u++; if(u>laengeschluessel) u=0; } //Entschlüsselung ENDE //Vergleich auf Gleichheit entschlüsselter Text mit Ursprungstext for(i=0;i<laenge;i++) { if(!(entschluesselt[i]==ursprungstext[i])) { printf("Es ist ein Fehler aufgetreten, entschluesselter Text entspricht nicht dem Ursprungstext. \n"); break; } } //Vergleich auf Gleichheit entschlüsselter Text mit Ursprungstext ENDE //Ausgabe entschlüsselter Text printf("\n Der entschluesselte Text lautet: \n"); for(i=0;i<laenge;i++) printf("%c",entschluesselt[i]); //Ausgabe entschlüsselter Text ENDE getchar(); return 0; }
Die Ausgabe liefert aber unnötige Zeichen (das Problem habe ich häufig) und
am Ende kommt das dabei raus:http://www.bilder-upload.eu/show.php?file=b23667-1431097541.jpg
Meine Frage nun: ist das zwischen diesen komischen Zeichen schon die richtige Ausgabe? weil die Lösung steht ja schon dort (zwischen diesen Zeichen) und wird weiter unten dann fehlerhaft wiederholt?
Kann es sein, dass er da einfach über meine Schleifen drüber etwas ausgibt weil ich die Endbedingung nicht richtig habe, oder ist das Zufall
-
Ich habe mir das nicht im Detail angetan.²
Aber ich gehe davon aus, dass du nirgends die '\0' als Stringende gesetzt hast.
Dann funktioniertstrlen
auch nicht.²Keine sprechende Variablennamen, der Kommentar dahinter sollte überflüssig sein.
-
DirkB schrieb:
Aber ich gehe davon aus, dass du nirgends die '\0' als Stringende gesetzt hast.
Dann funktioniertstrlen
auch nicht.Hallo, soweit ich das richtig verstanden habe, ließt fgets ja immer bis zum drücken von enter ein und dieses eingelesene char array bearbeite ich dann ja immer mit dem strlen() Befehl, dadurch sollte das ganze ja nur auf die tatsächlich eingegebenen Zeichen reduziert werden oder?
*Habe die Variabelnamen etwas ausdrücklicher gestaltet*
-
Du kopierst die Zeichenkette aber... allerdings ein Zeichen weniger (das '\n') und ohne ein '\0' am Ende.
-
strlen ermittelt die Länge vom String anhand der '\0'
Wenn die nicht vorhanden (oder falsch gesetzt) ist, kommt Müll raus.Bei allen (C-String-)Arrays die DU beschreibst, musst du das machen.
Alle Funktionen die Strings behandeln (auch fgets) halten sich daran.Und wenn du das weißt, dann nimmst du auch nicht mehr strlen in der Schleife sondern testest auf die '\0'
-
Ok danke euch, ich habe es nun gelöst und den richtigen Quellcode in den Startpost geschrieben, das Problem lag einerseits am fgets, habe jetzt einfach gets genommen, und zum anderen an der Tatsache, dass ich für den schlüssel in den Zählschleifen eine eigene Zählvariable verwenden musste (habe u dafür genommen).
Nun muss ich zum zweiten Teil der Aufgabe gehen, die daraus besteht, das komplette Programm nur mit Pointern anzusteuern und keine direkten Variablenwerte.
-
Pures Fett schrieb:
Ok danke euch, ich habe es nun gelöst und den richtigen Quellcode in den Startpost geschrieben, das Problem lag einerseits am fgets, habe jetzt einfach gets genommen, und zum anderen an der Tatsache, dass ich für den schlüssel in den Zählschleifen eine eigene Zählvariable verwenden musste (habe u dafür genommen).
gets
ist im aktuellen Standard von C (C11) nicht mehr vorhanden.Pures Fett schrieb:
Nun muss ich zum zweiten Teil der Aufgabe gehen, die daraus besteht, das komplette Programm nur mit Pointern anzusteuern und keine direkten Variablenwerte.
Hättest du unsere Vorschläge mit der '\0' umgesetzt, wäre das einfacher.
-
DirkB schrieb:
Pures Fett schrieb:
Ok danke euch, ich habe es nun gelöst und den richtigen Quellcode in den Startpost geschrieben, das Problem lag einerseits am fgets, habe jetzt einfach gets genommen, und zum anderen an der Tatsache, dass ich für den schlüssel in den Zählschleifen eine eigene Zählvariable verwenden musste (habe u dafür genommen).
gets
ist im aktuellen Standard von C (C11) nicht mehr vorhanden.Pures Fett schrieb:
Nun muss ich zum zweiten Teil der Aufgabe gehen, die daraus besteht, das komplette Programm nur mit Pointern anzusteuern und keine direkten Variablenwerte.
Hättest du unsere Vorschläge mit der '\0' umgesetzt, wäre das einfacher.
Oh das ist komisch wir lernen es auch immernoch mit gets und ich habe in Eigenregie fgets verwendet, dann sollte ich mir das doch nochmal ansehen, der entscheidende Punkt war ja, dass ich eine zweite Zählervariable gebraucht habe und nur eine verwendet habe.
Du meinst also zum Beispiel:
int i=0 fgets(bereich,maxgröße,stdin) while(bereich[i]!='\0') { anweisungen; i++; }
richtig?
Ich habe nun den zweiten Teil der Aufgabe fertig, verstehe den Sinn jedoch nicht, im Endeffekt habe ich einfach für jede Variable einen Zeiger deklariert und anstatt die variable anzusprechen halt immer *zeigerdervariable gemacht und es funktioniert:
#include <conio.h> #include <stdio.h> #include <string.h> #include <string.h> #define arraygroese 100 int main() { char ursprungstext[arraygroese]; //Ursprungstext char schluessel[arraygroese/2]; //Schlüssel (maximal halb so Groß wie zu verschlüsselnder Text) char verschluesselt[arraygroese]; //verschlüsselter Text char entschluesselt[arraygroese]; //entschlüsselter Text int i,u=0,laenge=0,laengeschluessel=0; //Zählvariable, Länge Ursprungstext und Länge Schlüssel char *zeigerursprungstext=&ursprungstext[arraygroese],*zeigerschluessel=&schluessel[arraygroese/2],*zeigerverschluesselt=&verschluesselt[arraygroese],*zeigerentschluesselt=&entschluesselt[arraygroese]; //deklarieren der Zeiger auf die char arrays int *zeigeri=&i,*zeigeru=&u,*zeigerlaenge=&laenge,*zeigerlaengeschluessel=&laengeschluessel; //deklarieren der Zeiger auf die Integer Variablen //Eingabe Satz printf("Bitte geben Sie den zu verschluesselnden Satz (maximal 100 Zeichen) ein: \n"); gets(ursprungstext); laenge=strlen(ursprungstext); //Eingabe Satz ENDE //Eingabe Schlüssel printf("\n Bitte geben Sie die Zeichen fuer die Verschluesselung ein (maximal 50): \n"); gets(schluessel); laengeschluessel=strlen(schluessel); //Eingabe Schlüssel ENDE //Verschlüsselung for(*zeigeri=0;*zeigeri<(*zeigerlaengeschluessel);(*zeiger)++) //zählt von 0 bis Länge Schlüssel { while((*zeigerursprungstext)[*zeigeri]==(*zeigerschluessel)[*zeigeri]) //Überprüfung der Zeichen auf Gleichheit { *zeigerverschluesselt[*zeigeri]=*zeigerursprungstext[*zeigeri]; //wenn die Zeichen gleich sind, wird es nicht verschlüsselt sondern einfach unverschlüsselt übertragen (*zeigeri)++; //und beim nächsten Zeichen weitergemacht } *zeigerverschluesselt[*zeigeri]=(*zeigerursprungstext)[*zeigeri]^(*zeigerschluessel)[*zeigeri]; //XOR-Verknüpfung } for(*zeigeri=*zeigerlaengeschluessel;*zeigeri<(*zeigerlaenge);(*zeigeri)++) //zählt von Länge des Schlüssels bis Länge Ursprungssatz (z.B. 50-99) und fängt beim Schlüssel wieder vorne an (i-laenge/2) { while((*zeigerursprungstext)[*zeigeri]==(*zeigerschluessel)[*zeigeru]) //zb 50-50 entspricht wieder dem ersten Element des Arrays des Schlüssels { *zeigerverschluesselt[*zeigeri]=*zeigerursprungstext[*zeigeri]; (*zeigeri)++; (*zeigeru)++; if((*zeigeru)>(*zeigerlaengeschluessel)) *zeigeru=0; } *zeigerverschluesselt[*zeigeri]=(*zeigerursprungstext)[*zeigeri]^(*zeigerschluessel)[*zeigeru]; //XOR-Verknüpfung // (laenge/2) entspricht erneutes durchlaufen des Schlüssels (*zeigeru)++; if((*zeigeru)>(*zeigerlaengeschluessel)) *zeigeru=0; } *zeigeru=0; //Verschlüsselung ENDE //Ausgabe verschlüsselter Text printf("\n Der verschluesselte Text lautet: \n"); for(*zeigeri=0;(*zeigeri)<(*zeigerlaenge);(*zeigeri)++) printf("%c", *zeigerverschluesselt[*zeigeri]); //Ausgabe verschlüsselter Text ENDE //Entschlüsselung for(*zeigeri=0;(*zeigeri)<(*zeigerlaengeschluessel);(*zeigeri)++) //zählt von 0 bis Schlüssellänge { while((*zeigerverschluesselt)[*zeigeri]==(*zeigerschluessel)[*zeigeri]) { *zeigerentschluesselt[*zeigeri]=*zeigerverschluesselt[*zeigeri]; (*zeigeri)++; } *zeigerentschluesselt[*zeigeri]=(*zeigerverschluesselt)[*zeigeri]^(*zeigerschluessel)[*zeigeri]; //XOR-Verknüpfung } for(*zeigeri=*zeigerlaengeschluessel;(*zeigeri)<(*zeigerlaenge);(*zeigeri)++) //zählt von Länge Schlüssel bis Länge verschlüsselter Satz { while((*zeigerverschluesselt)[*zeigeri]==(*zeigerschluessel)[*zeigeru]) { *zeigerentschluesselt[*zeigeri]=*zeigerverschluesselt[*zeigeri]; (*zeigeri)++; (*zeigeru)++; if((*zeigeru)>(*zeigerlaengeschluessel)) *zeigeru=0; } *zeigerentschluesselt[*zeigeri]=(*zeigerverschluesselt)[*zeigeri]^(*zeigerschluessel)[*zeigeru]; //XOR-Verknüpfung (*zeigeru)++; if((*zeigeru)>(*zeigerlaengeschluessel)) *zeigeru=0; } //Entschlüsselung ENDE //Vergleich auf Gleichheit entschlüsselter Text mit Ursprungstext for(*zeigeri=0;(*zeigeri)<(*zeigerlaenge);(*zeigeri)++) { if(!((*zeigerentschluesselt)[*zeigeri]==(*zeigerursprungstext)[*zeigeri])) { printf("Es ist ein Fehler aufgetreten, entschluesselter Text entspricht nicht dem Ursprungstext. \n"); break; } } //Vergleich auf Gleichheit entschlüsselter Text mit Ursprungstext ENDE //Ausgabe entschlüsselter Text printf("\n Der entschluesselte Text lautet: \n"); for(*zeigeri=0;(*zeigeri)<(*zeigerlaenge);(*zeigeri)++) printf("%c", *zeigerentschluesselt[*zeigeri]); //Ausgabe entschlüsselter Text ENDE getchar(); return 0; }
Macht keinen Sinn aber ist richtig so oder?