[CHANGE]fehler in xor verschlüsselung... 3 buffer io 2 buffer nio...



  • Den Modus "r+w" kannte ich noch nicht - dort sollte doch eher "r+b" stehen, oder (eventuell reicht sogar "rb"? Und anstelle von creat() kannst du auch fopen() verwenden mit dem Modus "wb" (allerdings bin ich nicht sicher, wie fopen() die Zugriffsrechte vorbelegt).

    Edit: Laut Man-Page setzt man: fopen die Zugriffsrechte auf 0666 (kann mittels umask() angepasst werden) - aber ausführen willst du das verschlüsselte File sowieso nicht, oder?



  • Das File kann behandelt werden wie jedes andere auch, dass stört mich nicht.

    Mit create klappt es ja auch, wieso sollte ich es umschreiben, hat dass einen Grund?

    Dass r+w lass ich so, da ich -wenn alles klappt- es so umschreibe dass direkt die Datei überschrieben wird, und ich sie nicht erst noch löschen muss.

    Ich werde mich jetzt mal an dass Entschlüsseln setzen -wo ich schon Fehler habe- und nochmal alles prüfen,
    du könntest mir ja gerne nochmal den unterschied zwischen fopen und create erklären...



  • "r+w" ist aber Käse - du kannst nur eine der Kennungen "r", "w" oder "a" beim Modus angeben. (und die Angabe "r+" reicht schon aus, um die Datei zum Lesen UND Schreiben zu öffnen)

    ("b" kannst du zusätzlich angeben und setzt damit die Datei in den Binärmodus - das bewirkt im wesentlichen, daß die Dateifunktionen nicht mehr zwischen \n und \r\n konvertieren)

    lippoliv schrieb:

    du könntest mir ja gerne nochmal den unterschied zwischen fopen und create erklären...

    fopen() ist eine Funktion des Ansi-Standards, create() ist eine systemspezifische Funktion (und afaik nur auf Unix-Derivaten verfügbar).



  • CStoll schrieb:

    [...]und afaik nur[...]

    Was ist afaik?

    Ok dann nutze ich r+.

    Müsste ich etwas unschreiben wenn ich r+b nutze?

    Ich habe ein Problem:

    if( '\n' != buf[i] )
        buf[i] = buf[i] ^ key[j];
    else
        j--;
    

    Wenn ich dass else auskommentiere sind es weniger Zeichen als wenn es in benutzung ist, wass ich echt überhaupt nicht nachvollziehen kann.

    Das j-- sorgt lediglich dafür, dass wenn beim überspringen eines \n im nächsten durchgang (beim nächsten buchstaben) der gleiche buchstabe aus dem key zum Verschlüsseln genutzt wird, wie der der eigentlich hätte bei dem \n kommen sollen.

    [edit]Dass liegt übrigens daran, dass wenn am ende der Datei eine Leerzeile ist, ein fehler auftritt... ich weißnoch nicht wie ich das fixen kann.[/edit]



  • lippoliv schrieb:

    CStoll schrieb:

    [...]und afaik nur[...]

    Was ist afaik?

    "as far as I know" = soweit ich weiß 😃

    Ok dann nutze ich r+.

    Müsste ich etwas unschreiben wenn ich r+b nutze?

    Ja, du kannst deine Sonderbehandlung für \n wieder rauswerfen.

    [/quote]Ich habe ein Problem:

    if( '\n' != buf[i] )
        buf[i] = buf[i] ^ key[j];
    else
        j--;
    

    Wenn ich dass else auskommentiere sind es weniger Zeichen als wenn es in benutzung ist, wass ich echt überhaupt nicht nachvollziehen kann.
    [/quote]Das kann ich auf die Schnelle auch nicht nachvollziehen. Hast du mal im Debugger verfolgt, was genau da passiert?



  • Dazu müsstest du mir sagen wie ich das machen kann:
    Editor Notepad++
    Compiler MinGW

    Ich habe jetza uf "r+b" umgestellt, und wenn ich dann das verschlüsseln auskommentiere werden bei \n immer noch 1 leerzeile hinzugefügt...

    Wieso?

    Des weiteren ist die Textdatei jetzt wieder größer:
    org.txt
    +186 KB
    +21.671 Zeilen
    +191.090 Zeichen

    new.txt
    +189 KB
    +6.551 Zeilen
    +194.168 Zeichen

    Wieso weicht dass bei den Zeichen so sehr ab?



  • Hast du auch die Ausgabedatei im Binärmodus geöffnet? (wenn ich die Manpage von create() betrachte, verwendet das Textmodus, also solltest du mindestens auf open() ausweichen (ich sehe gerade, open() hat kein Flag, um die Datei im Binärmodus zu setzen, also bleibt nur out=fopen(name,"wb"); )

    PS: Auf was für einem Betriebssystem entwickelst du eigentlich?



  • Ob man Windows Vista betriebssystem nennen kann... Ja eigentlich schon.

    Also ich habe umgestellt:

    int encryptingText( FILE *source, char *key, FILE *destination )
    {
    	char *buf;
    
    	buf = malloc( sizeof(char) * 1034 );
    
    	int textPos = 0,
    		keyPos = 0,
    		zahl = 0,
    		cryptedChar = 0,
    		end = 0;
    
    	//Solange Datei nicht zu Ende ist.
    	while( !feof( source ) && 0 == end )
    	{
    		memset( buf, '\0', 1024 );
    
    		fread( buf, sizeof(char), 1024, source );
    		textPos = 0;
    		keyPos = 0;
    
    		//solange kein \0 auftritt und textPos kleiner als 100 ist
    		while( '\0' != buf[textPos] && 1024 > textPos && 0 == end )
    		{
    			//Wenn das Ende der Datei nicht erreicht wurde
    			if( EOF != buf[textPos] )
    			{
    				cryptedChar++;
    
    				//Verschlüsseln
    				buf[textPos] = buf[textPos] ^ key[keyPos];
    
    				if( strlen( key )-1 == keyPos )
    					keyPos = -1;
    
    				textPos++;
    				keyPos++;
    			}
    			else
    				end = 1;
    		}
    		//In Datei schreiben
    		zahl += fwrite( buf, sizeof(char), textPos-1, destination );
    	}
    
    	free( buf );
    
    	return zahl;
    }
    

    Abweichungen:
    new.txt ist 187 Byte kleiner, das finde ich aber noch, nach dem Entschlüsseln.

    Ich lasse mal eben cryptedChar ausgeben:
    es wird quasi die größe der org.txt angezeigt, also durchläuft er alle Zeichen einmal, lässt aber einige fallen !?
    Fehler gefunden... "zahl += fwrite( buf, sizeof(char), textPos-1, destination );" muss "zahl += fwrite( buf, sizeof(char), textPos, destination );" sein.

    Jetzt gehts ans decrypten... 😞



  • Er hängt einfach ans ende der Entschlüsselten Datei -die echt entschlüsselt wird- so ca 100 mal das Codewort ran...

    sizeof( org.txt ) = 191.088 Bytes
    sizeof( new.txt ) = 191.088 Bytes
    sizeof( saveFile.crypt ) = 191.488 Bytes << entschlüsselte Datei
    
    lastRowOf( org.txt ) = "Hallo 0"
    lastRowOf( new.txt ) = "RVac>IFhxBA][He$	O]d|-"
    lastRowOf( saveFile.crypt ) = "Hallo 0oliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliveroliv"
    

    Wieso steht da das Codewort?

    #define READSIZE 1024
    
    [...]
    
    int decryptingText( FILE *file, char *key, FILE *dest )
    //Diese Funktion verschlüsselt die Datei auf die file zeigt. key wird als verschlüsselungs-Hilfe genommen.
    //Vorerst wird der so enstehende Text in dest gespreicher.
    //Returnwert: Die anzahl der geschriebenen Bytes
    {
    	char *buf;
    	buf = malloc( sizeof(char) * ( READSIZE + 10 ) );
    
    	int textPos = 0,
    		keyPos = 0,
    		zahl = 0,
    		encryptedChar = 0,
    		end = 0;
    
    	while( !feof( file ) && 0 == end )
    	{
    		memset( buf, '\0', READSIZE );
    
    		fread( buf, sizeof(char), READSIZE, file );
    		textPos = 0;
    		keyPos = 0;
    
    		//Es wird solange entschlüsselt, bis das Stringende erreicht ist, oder die maximal zu lesende anzahl an chars erreicht ist, oder aber das Ende der Datei erreicht wird.
    		while( '\0' != buf[textPos-1] && READSIZE > textPos && 0 == end )
    		{
    			//Bei EOF wird aufgehört zu entschlüsseln
    			if( EOF != buf[textPos] )
    			{
    				encryptedChar++;
    
    				//Verschlüsseln
    				buf[textPos] = buf[textPos] ^ key[keyPos];
    
    				if( strlen( key )-1 == keyPos )
    					keyPos = -1;
    
    				textPos++;
    				keyPos++;
    			}
    			else
    				end = 1;
    		}
    
    		zahl += fwrite( buf, sizeof(char), textPos, dest );
    	}
    
    	free( buf );
    
    	return zahl;
    }
    


  • kann es sein, dass ich im grunde ein und die Selbe Funktion nutzen kann?



  • Ja, du kannst (und solltest) nur eine De/Encrypt-Funktion benutzen, denn (ab)b = a.

    P.S: Du kannst dein Verfahren noch optimieren, indem du strlen( key ) nur einmalig vor der Schleife berechnest.



  • Th schrieb:

    P.S: Du kannst dein Verfahren noch optimieren, indem du strlen( key ) nur einmalig vor der Schleife berechnest.

    Dass würde nichts bringen da ich es ja nur einmal benutze, dass andere mal ist es strlen( buf ).

    Ich bentutze jetzt nur eine funktion und nie wird die ganze Datei verschlüsselt:
    so wies aussieht werden immer nur 1024 verschlüsselt...
    Beim entschlüsseln macht er die wieder gerade, und bei den nächsten quasi auch, aber da er beim entschlüsseln ist, verschlüsselt er die...

    Wieso?:

    int cryptingText( FILE *file, char *key )
    //Diese Funktion ver- und entschlüsselt die Datei auf die file zeigt. key wird als verschlüsselungs-Hilfe genommen.
    //Returnwert: Die anzahl der geschriebenen Bytes
    {
    	char *buf;
    	buf = malloc( sizeof(char) * ( READSIZE + 10 ) );
    
    	int textPos = 0,
    		keyPos = 0,
    		zahl = 0,
    		cryptedChar = 0,
    		end = 0;
    
    	long endOfFile = 0;
    
    	fseek( file, 0, 2 );
    	endOfFile = ftell( file );
    	fseek( file, 0, 0 );
    
    	while( ftell( file ) < endOfFile && 0 == end )
    	{
    		memset( buf, '\0', READSIZE );
    
    		fread( buf, sizeof(char), READSIZE, file );
    		textPos = 0;
    		keyPos = 0;
    
    		//Es wird solange verschlüsselt, bis das Stringende erreicht ist, oder die maximal zu lesende anzahl an chars erreicht ist, oder aber das Ende der Datei erreicht wird.
    		while( '\0' != buf[textPos] && READSIZE > textPos && 0 == end )
    		{
    			//Dass EOF wird nicht verschlüsselt, da beim entschlüsseln an dieser Stelle aufgehört werden muss.
    			if( EOF != buf[textPos] )
    			{
    				cryptedChar++;
    
    				//Verschlüsseln
    				buf[textPos] = buf[textPos] ^ key[keyPos];
    
    				if( strlen( key )-1 == keyPos )
    					keyPos = -1;
    
    				textPos++;
    				keyPos++;
    			}
    			else
    				end = 1;
    		}
    		if( strlen( buf ) < READSIZE )
    			end = 1;
    
    		fseek( file, zahl, 0 );
    		zahl += fwrite( buf, sizeof(char), textPos, file );
    	}
    
    	free( buf );
    
    	return zahl;
    }
    

    Versteh ich nich, wieso bleibt er nach dem ersten buffer stehen?



  • Das mit dem angehängten Schlüsselwort liegt wohl daran, daß fread() die gelesenen Daten nicht mit \0 abschließt. D.h. wenn du im letzten Schleifendurchlauf nur einen halb vollen Datenblock verschlüsselst, nimmst du den Inhalt der vorigen Ausgabe mit.

    (btw, die verschlüsselten Dateien dürften keine erkennbare Zeilenstruktur haben, schließlich werden NewLines wie jedes andere Zeichen mit verschlüsselt)



  • #define cTF_CANT_READ_ALL -1
    [...]
    
    int cryptingTextFile( FILE *file, char *key, int *failure )
    //Diese Funktion ver- und entschlüsselt die Datei auf die file zeigt. key wird als verschlüsselungs-Hilfe genommen.
    //Returnwert: Die anzahl der geschriebenen Bytes
    {
    	char *buf;
    	buf = malloc( sizeof(char) * ( READSIZE + 10 ) );
    
    	int textPos = 0,
    		keyPos = 0,
    		zahl = 0,
    		cryptedChar = 0,
    		end = 0;
    
    	long endOfFile = 0;
    
    	fseek( file, 0, SEEK_END );
    	endOfFile = ftell( file );
    	fseek( file, 0, SEEK_SET );
    
    	while( ftell( file ) < endOfFile && 0 == end )
    	{
    		memset( buf, '\0', READSIZE );
    
    		fread( buf, sizeof(char), READSIZE, file );
    		textPos = 0;
    		keyPos = 0;
    
    		//Es wird solange verschlüsselt, bis das Stringende erreicht ist, oder die maximal zu lesende anzahl an chars erreicht ist, oder aber das Ende der Datei erreicht wird.
    		while( READSIZE > textPos && 0 == end && '\0' != buf[textPos] )
    		{
    			//Dass EOF wird nicht verschlüsselt, da beim entschlüsseln an dieser Stelle aufgehört werden muss.
    			if( EOF != buf[textPos] )
    			{
    				if( '\0' == buf[textPos] )
    					;
    				else
    				{
    					cryptedChar++;
    
    					//Verschlüsseln
    					buf[textPos] = buf[textPos] ^ key[keyPos];
    					if( strlen( key )-1 == keyPos )
    						keyPos = -1;
    
    					textPos++;
    					keyPos++;
    				}
    			}
    			else
    				end = 1;
    		}
    		if( textPos < READSIZE && ftell( file ) < endOfFile )
    		{
    			end = 1;
    			*failure = cTF_CANT_READ_ALL;
    		}
    
    		fseek( file, zahl, SEEK_SET );
    		zahl += fwrite( buf, sizeof(char), textPos, file );
    	}
    
    	free( buf );
    
    	return zahl;
    }
    

    So also: Er verschlüsselt wunderbar, allerdings beim entschlüsseln, da bleibt es manchmal hängen, er entschlüsselt manche buchstaben nicht, lässt diese liegen...

    Habe ich da irgendwo einen Logikfehler drinne?
    Er macht dass ding immer voll (1024) schreibt also am Ende nicht das codewort, aber leerzeichen oder so... sehr komisch...



  • lippoliv schrieb:

    Th schrieb:
    P.S: Du kannst dein Verfahren noch optimieren, indem du strlen( key ) nur einmalig vor der Schleife berechnest.

    Dass würde nichts bringen da ich es ja nur einmal benutze, dass andere mal ist es strlen( buf ).

    Du rufst es aber in jedem Schleifendurchgang auf und da der Key konstant ist, reicht es doch, wenn du die Länge einmalig berechnest und dann nur noch die Variable abfragst (und nicht jedesmal die Länge des Keys wieder und wieder zu berechnen - auch wenn der Key sicherlich nicht so groß ist -)

    Aber du hast ja eher andere Probleme... benutze doch einfach den Debugger und steppe Schritt für Schritt durch dein Programm, dann sollten dir die Fehler auffallen -)



  • Irgendwer hatte dass schonmal erwähnt...
    Ich erinnere euch nochmal:
    Notepad++ und EXTERN MinGW, da Notepad++ keinen compiler mitliefert, dementsprechend auch kein Debugger.

    Also wie soll das funktionieren?



  • Also ich habe mir mal ausgeben lasen:

    geschrieben = fwrite( buf, sizeof(char), textPos, file );
    
    [...]
    
    printf( "\n\n%d =?= %d", textPos, geschrieben );
    

    Ich will überprüfen ob er mehr schreibt, als ich ihm sage... Er macht es nicht:

    ==========================
    Sie nutzen Version: 0.6.85
    ==========================
    
    Key: oli
    
    1024 =?= 1024
    
    530 =?= 530
    1554 Bytes bearbeitet!
    
    crypt state error
    

    Das ist meine Programmausgabe.

    1024 ist die Maximale buffergröße, und dann gibt er im 2ten durchlauf noch 530 aus, dass beides zusammen ergiebt 1554 bytes. So viele Zeichen sind in der Datei.

    Totzdem ist nach dem Programmlauf die Dateigröße bei 2048 Bytes( 2KiB halt ).
    Nach dem entschlüsseln ist die Dateigröße bei: 2578 Bytes,
    ABER: die letzten 1024 Zeichen sind kram, der Rest ist alles vernünftig...

    Nach dem Verschlüsseln sind 494 "NULL"s in der Datei am ende... 530+494 = 1024( 1 KiB )

    Er Schreibt aber doch lediglich 530Zeichen, wie kommen also diese dinger zu stande? MFG

    [edit]
    Das problem oben ist beseitigt...

    Ich habe ein interessantes anderes Problem.
    Während der Verschlüsseelung geht er so vor:

    3 Buffer werden vernünftig verschlüsselt,
    /wiederholung:...........................
    2 Buffer werden fehlerhaft verschlüsselt,
    1 Buffer wird richtig verschlüsselt
    ...........................:gnulohredeiw
    /

    Wie kommt sowas zu stande? Es ist eine Whileschleife:

    //solange das Ende der Datei nicht erreicht wurde UND kein fehler aufgetreten ist
    		while( ftell( file ) < endOfFile && 0 == end )
    		{
    			memset( buf, '\0', READSIZEcrypt );
    
    			read = 0;
    
    			while( read < READSIZEcrypt && ftell( file ) < endOfFile )
    			{
    				buf[read] = fgetc( file );
    				read++;
    			}
    
    			textPos = 0;
    
    			//Es werden so viele Zeich Ver- oder Entschlüsselt, wie eingelesen wurden.
    			do
    			{
    				//Ver- und Entschlüsseln
    				buf[textPos] = buf[textPos] ^ key[keyPos];
    
    				//Da der schlüssel oft kürzer als der zu verschlüsselnde Text ist, muss der schlüssel wiederholt werden
    				if( keyLen == keyPos )
    					keyPos = 0;
    				else
    					keyPos++;
    
    				textPos += 1;
    			}while( textPos < read );
    
    			//Wenn nicht alle einzulesenden Zeichen eingelesen wurden und die Datei nicht am Ende angelangt ist,
    			//ist ein Fehler aufgetreten
    			if( textPos < READSIZEcrypt && ftell( file ) < endOfFile )
    			{
    				end = 1;
    				*state = cTF_CANT_READ_ALL;
    			}
    			//Wenn nicht alle einzulesenden Zeichen eingelesen wurden und das Dateiende erreicht wurde,
    			//ist das Verschlüsseln erfolgreich abgeschlossen
    			else if( textPos <= READSIZEcrypt && ftell( file ) == endOfFile )
    				*state = cTF_READ_ALL;
    
    			fseek( file, zahl, SEEK_SET );
    			geschrieben = fwrite( buf, sizeof(char), read, file );
    
    			zahl += geschrieben;
    		}
    

    Programmausgabe:

    ==================================
    Sie nutzen Version: 1.15.17.080123
    ==================================
    
    Key: irgendwas
    
    4860 Bytes bearbeitet!
    Somit wurde die gesamte Datei bearbeitet
    
    Drücken Sie eine beliebige Taste . . .
    

    Anhand der Zeile unter der Byte zahl sieht man, dass das Program erfolgreich war.
    4860 entspricht der verwendeten Zeichen in der Datei und halt deren Größe in Bytes.



  • sorry für den 3. Post...
    Gibt es irgend ein Tool (keinen neuen Editor) der meinen Code schrittweise durchgeht?
    Ich meine es kann ja nicht sein, dass bei 1 funktion 2 gute ergebnisse 2 schlechte 1 gutes 2 schlechte... ergebnisse rauskommen...

    Irgendwo muss da ja ein fehler sein oder?...



  • Da gibt's sicher genug - such mal nach "Debugger" (sowas gibt's bestimmt auch ohne Komplett-IDE). Und wenn alle Stricke reißen, bleibt immer noch cerr-Debugging - du lässt dir an ausgewählten Stellen der Funktion deine Variableninhalte nach cerr/stderr ausgeben und vergleichst diese Werte mit deinen Erwartungen.



  • Ich bin hier und du nicht.5
    Ich bin hDrücken Sie eine beliebige Taste . . .
    ier und du nicht.6
    

    1ter Break... OK

    Ich bin hier und du nicht.0
    Ich bin hier und dDrücken Sie eine beliebige Taste . . .
    ier und du nicht.6
    Ich bin hier und du nicht.7
    

    Da Fehlt "u nicht.\nIch bin h" das sind 18 Zeichen!?

    Ich bin hier und du nicht.0
    Ich bin hier und dDrücken Sie eine beliebige Taste . . .
    ier und du nicht.6
    Ich bin hier und du nicht.7
    

    3ter Break... Fehler

    So siehts aus
    1 OK
    2 Falsch
    3 Falsch
    4 Falsch
    5 Falsch
    6 Falsch
    7 Falsch + schneidet Dateiende ab...

    hängt das mit folgendem zusammen:?

    memset( buf, '\0', READSIZEcrypt );
    read = 0;
    
    while( read < READSIZEcrypt && ftell( file ) < endOfFile )
    {
        buf[read] = fgetc( file );
        read++;
    }
    [...]
    fseek( file, zahl, SEEK_SET );
    geschrieben = fwrite( buf, sizeof(char), textPos, file );
    zahl += geschrieben;
    

    Ist da ein denkfehler drinne?


Anmelden zum Antworten