| 

.NET C# Java Javascript Exception

7
Hallo liebe CK-Com,

heute ist mir ein sehr komisches Problem begegnet und ich hoffe, dass ich hier mit eurer Hilfe ein Lösung oder zumindest eine Erklärung finde.
Ich habe mit C# eine Textdatei mit der Ceasar-Chiffre im ASCII Code verschlüsselt (heißt ich nutze nicht nur das Alphabet sondern alle 256 Zeichen des ASCII-Zeichensatzes) bei einem Schlüssel von 52. Dabei verwende ich zum Schreiben der verschlüsselten Datei einen TextWriter/StreamWriter mit Encoding.ASCII.
Wenn ich nun versuche, die Datei mit C mit folgendem Code wieder zu entschlüsseln, dann werden nur die Satzzeichen (Komma, Punkt, Leerzeichen) und einige Großbuchstaben (B, F) (aber nicht alle, z.B. "V" nicht) richtig angezeigt in der entschluesselt.txt:
#include <stdio.h>
#include <conio.h>
#include <iostream.h>

void main(void)
{
FILE *datei1,*datei2;
datei1=fopen("verschluesselt.txt","r+t");
datei2=fopen("entschluesselt.txt","w+t");
char zeichen;
int verschiebung=4;
zeichen=fgetc(datei1);
while (!feof(datei1))
{
fputc((char)((int)zeichen-verschiebung),datei2);
zeichen=fgetc(datei1);
}
fclose(datei1);
fclose(datei2);
cout<<"FERTIG!";
getch();
}

auch das Ändern des Modus bei fopen auf "rb"/"wb" ändert daran leider nichts.

P.S.: Verschlüssele ich mit C anstatt mit C# ist die verschluesselt.txt "nur" 3 Bytes kleiner... was aber auch heißt, dass beide Dateien doch irgendwie unterschiedlich sind.

Hat jemand eine Idee/Ahnung, woran das liegen könnte, und wie man das Problem lösen könnte? (Ich vermute den Fehler beim Schreiben der Datei...)

P.P.S.: C# Code zum Schreiben der Datei:
int i = 52;
KryptoNet.Caesar asciiCeasar = new KryptoNet.Caesar(KryptoNet.Caesar.EncryptionMode.ASCII);
string TextEncrypted = String.Empty;
using(FileStream fsWriteEncrypted =
new FileStream(Path.Combine(TargetFolder, "verschluesselt.txt"), FileMode.Create, FileAccess.Write, FileShare.None))
{
using(TextWriter twWriteEncrypted = new StreamWriter(fsWriteEncrypted, Encoding.ASCII))
{
TextEncrypted = asciiCeasar.Encrypt(TextNormal, i);
twWriteEncrypted.Write(TextEncrypted);
}
}


//EDIT:
Als kleine Zusatzinfo: Wenn ich mit C verschlüssele kann ich mit der gleichen Methode (invertierter Key) mit C# entschlüsseln... das Problem ist also die Richtung von C# nach C!

//EDIT2:
Hier mal die Inhalte beider verschlüsselten Dateien
C:
Š£¢T˜™¢Tv •©™¢Tv™¦›™¢TŸ£¡¡™¢T«¦`>©¢§™¦T€™œ¦™¦T§¨T›™¢•©§£T˜££šT«™T«¦`>§¨™—Ÿ¨T™¦T˜™¢Tz¢›™¦T¢T˜™¢T‡¨™—Ÿ™¦T§™œ¨T™¦T•©§T«™Tv£¦§Tv™—Ÿ™¦`>ª£¢T˜™¢Tv •©™¢Tv™¦›™¢TŸ£¡¡™¢T«¦U
C#:
???T???Tv?????Tv?????T??????T???`A>?????T??????T???T???????T????T???T???`A>??????T??T???Tz?????T??T???T???????T?????T??T???T???Tv????Tv?????`A>???T???Tv?????Tv?????T??????T???U
Ein paar "Ähnlichkeiten" (selbe Zeichen an gleicher Stelle) gibt es schon, aber leider nicht viel...
News:
19.04.2012
Karill Endusa 1,5k 1 9
Du schreibst "nur 3 Bytes kleiner". Hast Du mal die C#-verschlüsselte und die C-verschlüsselte Datei in einem Diff angeschaut? Sind es also nur 3 Bytes weniger oder unterscheidet sich im Rest der Files auch einiges?
ffordermaier 19.04.2012
es sind sogar nur einige wenige Zeichen gleich... der Unterschied zwischen beiden Dateien beträgt mehr als 95% grob geschätzt
Karill Endusa 19.04.2012
4 Antworten
3
Mein Vermutung ist, dass das Encoding in den Files nicht passt. Ich habe das Gefühl, dass das Encoding.ASCII in C# mit dem in C generierten Textfile irgendwie klarkommt, aber andersrum eben nicht.
Um Caesar zu rechnen, kannst Du ja ASCII verwenden, aber versuch doch mal, das Encoding im File zu ändern (auf beiden Seiten). Also z.B. Unicode. Gibts nicht auch ein fgetwc in C?
19.04.2012
ffordermaier 8,3k 2 9
gespeichert mit C# als Unicode und dann über fgetwc gearbeitet, aber das Ergebnis sieht nicht unbedingt besser aus... danke trotzdem für den vorschlag
Karill Endusa 19.04.2012
+1
also:
speichern in unicode mit c#
lesen in C mit Mode "rb" (vorher "r+t") und fgetwc()

nun habe ich in der entschluesselt.txt fast den klartext, außer ein zeichen ganz am anfang der Datei :)
Karill Endusa 19.04.2012
1
Ohne jetzt direkt die Lösung zu wissen.. beim Caesar Chiffre werden doch die Buchstaben durch Verschiebung kodiert. Wenn man über das Ende der Tabelle hinausschiebt muss der Zeiger wieder auf den Anfang gesetzt werden, d.h. bei einer Verschiebung von 4 müsste dann W zu A werden. Du hast allerdings keinen Code der das berücksichtigt (wobei ich nicht weiss, was das KryptoNet.Caesar intern macht).
19.04.2012
puls200 3,8k 6
das ist schon berücksichtigt (Position Modulo Feldgröße), aber ich habe auch gesagt, dass die verschiebung 52 beträgt ... und selbst "z" mit dem Wert 122 geht mit +52 nicht über das Ende der (erweiterten) ASCII-Tabelle hinaus (256 Zeichen)
Karill Endusa 19.04.2012
okee.. sonst könnte ich mir ggf. vorstellen, dass es ein Problem mit char in C geben könnte, weil Signed. evtl. ist unsigned char besser für "zeichen"?
puls200 19.04.2012
geändert aber ohne eine Änderung des Ergebnisses... wie in dem Kommentaren zur Frage mitlerweile nachzulesen, unterscheiden sich aber auch die beiden verschlüsselten Dateien aus C# und C stark. Der "Fehler" muss also bei C# liegen (ich kann das mit C# verschlüsselte aber damit wieder entschlüsseln... und das mit C verschlüsselte auch)
Karill Endusa 19.04.2012
1
Nur so ins blaue geschossen.

Was passiert, wenn du deinem StreamWriter als Encoding mal was anderes als ASCII übergibst, z.B. Default oder Unicode.
19.04.2012
multi1209 788 8
Default ist UTF8 aber davon abgesehen habe ich alle Encodings durchprobiert. Von den ersten Zeichen her gesehen besteht bei Unicode die meiste Ähnlichkeit zwischen den beiden verschlüsselten Dateien, aber es gibt immer noch zu viele Unterschiede (nicht nur, dass die Unicode-Datei aus C# mehr als doppelt so groß ist)
Karill Endusa 19.04.2012
1
Bei Unicodedateien wird doch am Anfang der Datei noch die "Byte Order Mark" angegeben.
http://de.wikipedia.org/wiki/Byte_Order_Mark

Wahrscheinlich ist das dein zusätzliches Zeichen

EDIT: Sollte eigentlich ein Kommentar werden :-)
19.04.2012
multi1209 788 8

Stelle deine .net-Frage jetzt!