[CHANGE]fehler in xor verschlüsselung... 3 buffer io 2 buffer nio...
-
Wie hast du deine Datei(en) eigentlich geöffnet?
(btw, hat es einen Grund, daß du die Eingabedatei als FILE* übergibst, die Ausgabedatei aber als Unix File Deskriptor (int)?)
-
source = fopen( argv[1], "r+w" ); [...] datei = creat( "cryptedFile.cf", 0777 );
Ich weiß nicht, ob es einen speziellen grund hatte, dass ich create genommen habe, aber dass ist ja auch kein unterschied zu fopen mit dem create parameter oder?
[edit]die Lösung ist
if( '\n' != buf[i] ) buf[i] = buf[i] ^ key[j];
dann ist lediglich 1 zeichen zu viel vorhanden, dass bekomm ichauch noch hin...
Danke[/edit]
-
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 MinGWIch 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 Zeichennew.txt
+189 KB
+6.551 Zeilen
+194.168 ZeichenWieso 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?...