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 funktioniert strlen 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 funktioniert strlen 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?


Anmelden zum Antworten