Programm zum Verschlüsseln von Texten



  • In der Schule haben wir die Aufgabe bekommen den Textinhalt einer .txt Datei zu verschlüsseln. Wie wir das machen ist egal.

    Eine andere Gruppe muss ein Programm schreiben, welches die Texte wieder entschlüsselt (ohne über die Verschlüsselung der Anderen bescheid zu wissen).

    Ich wollte es eigentlich mal so versuchen:

    i ist gleich null.
    Quelldatei, Zieldatei und Key werden abgefragt.
    Ob verschlüsselt oder entschlüsselt werden soll.
    Zeichenlänge von Key wird in strLength gespeichert.
    
    while ((aValue = getNextSourceChar()) != EOF){ //Solange Zeichen lesen, bis EOF geliefert wird
    		if(encrypt==1){               //verschlüsseln
    			currentChar = (char)aValue ^ (char)key[i];
    			var1 = currentChar << 3;
    			var2 = currentChar >> 5;
    			currentChar = var1 ^ var2;
    		}
    		else{                        //entschlüsseln
    			currentChar=(char)aValue ^ (char)key[i];
    			var1 = currentChar << 5;
    			var2 = currentChar >> 3;
    			currentChar = var1 ^ var2;
    		}
    		i++;
    		if(i > (strLength - 1)){
    			i = 0;
    		}
    
    		putNextTargetChar(currentChar);
    		//Zeichen in Ausgabedatei schreiben
    
    	}
    

    Nur habe ich jetzt das Problem, dass ich den Text nur Teilweise entschlüsselt bekomme. An manchen Stellen werden Sonderzeichen dargestellt und nicht der richtige Buchstabe.

    Könnt ihr mir weiterhelfen?
    Ich weiß nicht, ob das was ich mir jetzt zur Verschlüsselung ausgesucht habe überhaupt gut ist^^
    Aber vllt könnt ihr mir dazu auch etwas sagen.

    MfG

    RapistseinHobby



  • erstmal kann bei den shifts was verloren gehen. ausserdem scheint die reihenfolge beim entschlüsseln falsch zu sein und wahrscheinlich ist a = (a<<3) ^ (a>>5) auch garnicht umkehrbar (jedenfalls nicht so).
    🙂



  • Wie fricky schon sagte, beim shiften schiebst du die Zahlen über den Zahlenbereich hinaus und verlierst damit unwiederbringlich Daten.

    Eine einfache und sehr effektive Methode wäre

    while ((aValue = getNextSourceChar()) != EOF){ //Solange Zeichen lesen, bis EOF geliefert wird
            const int schluessel = 08154711; //geheimer Schlüssel
            srand(schluessel); //setze den Zufallsgenerator auf Schlüsselzustand
            currentChar = aValue^(char)rand(); //Verschlüsseln oder Entschlüsseln
            putNextTargetChar(currentChar); //Zeichen in Ausgabedatei schreiben
    }
    

    Wahrscheinlich solltest du dir durchlesen was srand und rand tun. Es ist nicht zufällig, aber ziemlich nah dran. Du kannst auch statt eines festen Schlüsselwertes ein Passwort abfragen welches dann in ein int konvertiert als Schlüssel dient. Sollte locker reichen um deine Mitschüler scheitern zu lassen 😉



  • nwp2 schrieb:

    Wie fricky schon sagte, beim shiften schiebst du die Zahlen über den Zahlenbereich hinaus und verlierst damit unwiederbringlich Daten.

    Stimmt doch gar nicht.

    nwp2 schrieb:

    Eine einfache und sehr effektive Methode wäre...

    Ja, die ist sehr gut. srand() muß noch vor die Schleife.



  • volkard schrieb:

    nwp2 schrieb:

    Wie fricky schon sagte, beim shiften schiebst du die Zahlen über den Zahlenbereich hinaus und verlierst damit unwiederbringlich Daten.

    Stimmt doch gar nicht.

    stimmt auch nicht, hab mich verguckt. und zurückrechnen geht sogar auch (mit unsigned char jedenfalls).
    🙂



  • Tut's das normale Caesar-Verschiebechiffre etwa nicht mehr 🙄

    char buf = 'A';
    std::cout<< (char) (buf + 1);
    


  • Kóyaánasqatsi schrieb:

    Tut's das normale Caesar-Verschiebechiffre etwa nicht mehr.

    char buf = 'A';
    std::cout<< (char) (buf + 1);
    

    ist wohl zu einfach zu cracken für die anderen mitschüler, die das ja knacken sollen. wozu überhaupt der type cast? streikt 'cout' sonst? *fg*
    nimm im zweifelsfall 'putchar'.
    🙂



  • Ich hab mich auch mal an einer einfach Verschlüsselung versucht, nur leider gibt er mir sowohl beim verschlüsselten als auch bei dem unversclüsselten das gleiche aus. 😞

    wäre nett, wenn ihr euch das mal ansehen könntet.

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 22
    
    FILE *in_file, *out_file, *fopen();
    
    main()
    {
          int decrypt = 0;
          char buffer[MAX], eng[2];
          int valid = 0, loop = 0;
    
          while(valid == 0)
          {
           printf("Wählen Sie die Vorgehensweise:\n\t1 - Verschluesseln\n\t2 - Entschluesseln\n");
           fgets(eng, 2, stdin);
           sscanf(eng, "%i", &decrypt);
           if( (decrypt == 1) || (decrypt == 2) )
           {
              valid = 1;
           }
           else
           {
              printf("\n\nUngueltige Eingabe!\n");
              getch();
              system("cls");
              fflush(stdin);
              valid = 0;
           }
          }
    
          if(decrypt == 1)
          {
                     if( (in_file = fopen("unverslt.txt", "r")) == NULL)
                     {
                         printf("\nunverslt.txt konnte nicht geoeffnet werden!");
                         getch();
                         exit(1);
                     }
                     for(;loop <= MAX;loop++);
                               buffer[loop] = getc(in_file);
                     fclose(in_file);
    
                     loop = 0;
                     for(;loop <= MAX;loop++);
                               buffer[loop] << 1;
    
                     loop = 0;
                     if( (in_file = fopen("verslt.txt", "w")) == NULL)
                     {
                         printf("\nverslt.txt konnte nicht geoeffnet werden!");
                         getch();
                         exit(1);
                     }
                     for(;loop <= MAX;loop++)
                               fprintf(in_file, "%c", buffer[loop]);
                     fprintf(in_file, "%c", buffer[loop]);
                     fclose(in_file);
          }
    
          if(decrypt == 2)
          {
                     if( ((in_file = fopen("verslt.txt", "r")) == NULL) || ((out_file = fopen("unverslt.txt", "w")) == NULL) )
                     {
                         printf("\nFILE konnte nicht geoeffnet werden!");
                         getch();
                         exit(1);
                     }
    
                     loop = 0;
                     for(;loop <= MAX;loop++)
                               buffer[loop] = getc(in_file);
    
                     loop = 0;
                     for(;loop <= MAX; loop++)
                     {
                               buffer[loop] >> 1;
                               fprintf(out_file, "%c", buffer[loop]);
                     }
                     fclose(in_file);
                     fclose(out_file);
          }                 
    }
    


  • ;fricky schrieb:

    wozu überhaupt der type cast?

    Um den ASCII-Wert (den man erhält) als ASCII-Zeichen darzustellen!?



  • Kóyaánasqatsi schrieb:

    ;fricky schrieb:

    wozu überhaupt der type cast?

    Um den ASCII-Wert (den man erhält) als ASCII-Zeichen darzustellen

    wäre unnötig, wenn du z.b. putchar oder printf ("%c", ...) genommen hättest:

    putchar ('A'+1); // B
    printf ("%c", 'A'+2); // C
    

    ^^gibt immer zeichen aus.

    _qwert: wie arbeitet denn deine verschlüsselung?
    🙂



  • ;fricky schrieb:

    ... ^^gibt immer zeichen aus.

    Du kleiner Rüpel du, habe std::cout benutzt (Typischer C++-Instinkt^^).



  • ;fricky schrieb:

    _qwert: wie arbeitet denn deine verschlüsselung?
    🙂

    Also meine Verschlüsselung sollte eigentlich jedes Zeichen der "unverslt.txt" Datei einlesen, es um 1Bit nach links verschieben, und dann in die Datei "verslt.txt" schreiben.
    (oder umgekehrt, wenn am Anfang "entschlüsseln" gewählt wurde)

    Das mit dem Verschlüsseln klappt anscheinend (in der verslt.txt steht nur schrott^^ ...nur leider immer das gleiche, egal was ich verschlüsseln lasse)
    Und beim Entschlüsseln kommt leider auch nichts Gescheites bei raus, obwohl ich jedes Zeichen wieder um einen Bit nach rechts verschiebe -.-

    Deshabl wollte ich fragen, wo denn der (wahrscheinlich semantische) Fehler liegt?
    🙂



  • _qwert schrieb:

    Also meine Verschlüsselung sollte eigentlich jedes Zeichen der "unverslt.txt" Datei einlesen, es um 1Bit nach links verschieben, und dann in die Datei "verslt.txt" schreiben.
    (oder umgekehrt, wenn am Anfang "entschlüsseln" gewählt wurde)

    Dabei gehen die MSBs verloren und lassen sich nicht wieder herstellen.
    Bsp:
    Das Byte mit dem binären Wert 10000000 soll nach deiner Methode verschlüsselt werden. ( 10000000 << 1 ) == 00000000
    Das verschlüsselte Byte ist jetzt also 00000000
    Das MSB ging flöten.

    Was du brauchst, ist eine Bitrotation.

    MFG



  • Hey ich schlage eine Permutationschiffre vor. 2 Permutationen mit unterschiedlicher Laenge sollte als sicher in diesem Rahmen angesehen werden. Sehr einfach zu implementieren. Auch bei der Benutzung von einer Permutation muss man sich schon ein wenig was einfallen lassen, um den Text zu entschluesseln.



  • mr. bingo bongo schrieb:

    _qwert schrieb:

    Also meine Verschlüsselung sollte eigentlich jedes Zeichen der "unverslt.txt" Datei einlesen, es um 1Bit nach links verschieben, und dann in die Datei "verslt.txt" schreiben.
    (oder umgekehrt, wenn am Anfang "entschlüsseln" gewählt wurde)

    Dabei gehen die MSBs verloren und lassen sich nicht wieder herstellen.
    Bsp:
    Das Byte mit dem binären Wert 10000000 soll nach deiner Methode verschlüsselt werden. ( 10000000 << 1 ) == 00000000
    Das verschlüsselte Byte ist jetzt also 00000000
    Das MSB ging flöten.

    Was du brauchst, ist eine Bitrotation.

    MFG

    Danke, genau dasselbe hab ich grad auch bei wikipedia gelesen^^
    Nur leider steht dort nicht, wie man eine bitrotation macht.
    Das muss ich doch mit einem logischen Oder machen, oder?

    kannst du vllt. ein Beispiel geben, wie ich die bits von buffer[loop] zuerst um 1Bit nach rechts, und dann beim entschlüsseln un 1Bit nach links rotieren lasse?
    (oder umgekehrt, wenn es einfacher ist)

    EDIT:
    Ich benutze zum verschlüsseln jetzt

    buffer[loop] = (buffer[loop] << 1) | (buffer[loop] >> (8 - 1) );
    

    und zum entschlüsseln

    buffer[loop] = (buffer[loop] >> 1) | (buffer[loop] << (8 - 1) );
    

    Aber obwohl ich das durchgerechnet habe, und die Buchstaben beim Entschlüsseln wieder zum Vorschein kommen sollten, tun sie das nicht. 😞



  • _qwert schrieb:

    Aber obwohl ich das durchgerechnet habe, und die Buchstaben beim Entschlüsseln wieder zum Vorschein kommen sollten, tun sie das nicht. 😞

    Das sollte eigentlich gehen, wenn du unsigned char nimmst.
    signed char zieht beim Rechtsshift einsen von links nach, das ergibt dann Schrott.



  • Big Brother schrieb:

    signed char zieht beim Rechtsshift einsen von links nach...

    Bei negativen chars.



  • ich weis nicht, es klappt einfach nicht. 😞
    Ich habs jetzt in unsigned char geändert, aber nun schreibt er nur noch 8 "Leerzeichen" in die verschlüsselte Datei. -.-

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 10
    
    FILE *in_file, *out_file, *fopen();
    
    main()
    {
          int decrypt = 0;
          unsigned char buffer[MAX] = { 0 };
          char eng[2] = { 0 };
          int valid = 0, loop = 0;
    
          while(valid == 0)
          {
           printf("Wählen Sie die Vorgehensweise:\n\t1 - Verschluesseln\n\t2 - Entschluesseln\n");
           fgets(eng, 2, stdin);
           sscanf(eng, "%i", &decrypt);
           if( (decrypt == 1) || (decrypt == 2) )
           {
              valid = 1;
           }
           else
           {
              printf("\n\nUngueltige Eingabe!\n");
              getch();
              system("cls");
              fflush(stdin);
              valid = 0;
           }
          }
    
          if(decrypt == 1)
          {
                     if( (in_file = fopen("unverslt.txt", "r")) && (out_file = fopen("verslt.txt", "w")) == NULL)
                     {
                         printf("\nFILE konnte nicht geoeffnet werden!");
                         getch();
                         exit(1);
                     }
                     for(;loop < MAX;loop++);
                               buffer[loop] = fgetc(in_file);
    
                     loop = 0;
                     for(;loop < MAX;loop++);
                               buffer[loop] = (buffer[loop] << 7) | (buffer[loop] >> (8 - 7) );
                     buffer[loop] = 0x00;
    
                     loop = 0;
                     for(;loop < MAX;loop++)
                               fprintf(out_file, "%c", buffer[loop]);
                     fclose(in_file);
                     fclose(out_file);
          }
    
          if(decrypt == 2)
          {
                     if( ((in_file = fopen("verslt.txt", "r")) == NULL) || ((out_file = fopen("unverslt.txt", "w")) == NULL) )
                     {
                         printf("\nFILE konnte nicht geoeffnet werden!");
                         getch();
                         exit(1);
                     }
    
                     loop = 0;
                     for(;loop < MAX;loop++)
                               buffer[loop] = fgetc(in_file);
    
                     loop = 0;
                     for(;loop < MAX; loop++)
                     {
                               buffer[loop] = (buffer[loop] >> 7) | (buffer[loop] << (8 - 7) );
                     }
                     buffer[loop] = 0x00;
    
                     loop = 0;
                     for(;loop < MAX; loop++)
                               fprintf(out_file, "%c", buffer[loop]);
                     fclose(in_file);
                     fclose(out_file);
          }                
    }
    

    bin etwas ratlos...:(



  • Semikolon wegmachen:

    for(;loop < MAX;loop++); // <- das letzte da
    
    for(;loop < MAX;loop++); // <- hier auch
    


  • Guckst du ratgebers Tip und guckst du meinen Tip:

    Komm mal vom Spaghetticode weg.
    Organisiere das Programm in Teilaufgaben, die du in kleinen Funktionen/Modulen erledigst.
    So steigst du dann auch selber nach einer längeren Programmierpause besser durch.
    Wenn du schon die Datei komplett im Array hast, dann übergib es doch
    an eine kleine Funktion. Das Speichern/Lesen kann wieder eine andere Funktion erledigen, usw.

    Bsp:

    void encode ( char* s )
    {
    	unsigned char* a = (unsigned char*)s;
    	while(*a)
    		*a = ( *a << 1 ) | ( *a++ >> 7 );
    }
    
    char decode ( char* s )
    {
    	unsigned char* a = (unsigned char*)s;
    	while(*a)
    		*a = ( *a >> 1 ) | ( *a++ << 7 );
    }
    

    Dazu das Testprogramm:

    int main() 
    { 
    	char def[] = "There is no other, like Big Brother!";
    	encode(def);
    	puts(def);
    	decode(def);
    	puts(def);
    	return 0;
    }
    

    Obige encode Funktion mit festem "Rotationswert" lässt sich relativ einfach
    in eine echte Rotationsfunktion erweitern:

    // Rotiere jedes Byte n Bits nach links.
    void rotl ( char* s, int n )
    {
    	unsigned char* a = (unsigned char*)s;
    	if ( 0 == (n %= CHAR_BIT) ) return;
    	while(*a) *a = ( *a << n ) | ( *a++ >> (CHAR_BIT - n) );
    }
    
    // Rotiere jedes Byte n Bits nach rechts.
    void rotr ( char* s, int n )
    {
    // ... to be written yet ...
    }
    

Log in to reply