Problem bei .doc/.xls Dateien beim Öffnen
-
Also, ich schreibe gerade ein Programm, mit dem ich jegliche Datei einlesen,
verschlüsseln, und dann wieder unter dem gleichen namen abspeichern kann.Die Verschlüsselung ist nicht das problem, das mach ich über XOR (^), was
für die Anwendung völlig ausreicht.Wenn ich txt dateien, also reine Textdateien einlese, funktioniert es einwandfrei,
das Programm verschlüsselt die Dateien, und gibt sie wieder 100% gleich aus,
wenn man sie 'rückverschlüsselt'.Bei Officedateien siehts aber anders aus, da läuft auch alles sauber, aber in der
Datei steht nacher nur noch schrott.Mein Quellcode:
bool crypt::CryptFile(std::string path, std::string filename) { std::string text; ifstream in("C:\\weller\\test\\test.xls", ios::in|ios::binary); if(!in) return false; char c; while(!in.eof()) { c =in.get(); if(c != EOF) text += c; } in.close(); text = Crypt(text,wnd); ofstream out("C:\\weller\\test\\test.xls", ios::trunc|ios::binary/*|ios::out*/); if(!out) return false; out<<text.c_str(); out.close(); return true; }
Was mach ich Falsch, bzw. woran könnte es liegen ?
ist out<<text.c_str() nicht für binär geeignet ?Ich vermute den Fehler bei der Dateiabspeicherung, kann mir aber keinen Reim draus machen
mfg. Devil
-
evtl. liegt es auch an der XOR-Funktion, da dort evtl. einige zeichen überschrieben
werden, wieso, kann ich mir aber net erklären.std::string crypt::Crypt(std::string text,HWND hwnd) { char c; int leng = s.length(),pi = 0, i; for(i =0; i < text.length(); i++) { c =text[i]^s[pi]; if(c != EOF) { if(c > 31 ||c=='\r'||c=='\n'||c=='\t'/**/) text[i]^=s[pi]; } if(pi > leng) pi++; else pi =0; } return text; }
Ich hatte schon mal probleme, weil er beim Xoren steuerungszeichen erzeugte.
Hab ich irgendwelche zeichen übersehen, wo er nicht xoren dürfte ?Devil
[ Dieser Beitrag wurde am 28.05.2003 um 10:30 Uhr von devil81 editiert. ]
-
std::string crypt::Crypt(std::string text,HWND hwnd) { char c; int leng = s.length(),pi = 0, i; for(i =0; i < text.length(); i++) { c =text[i]^s[pi]; if(c != EOF) // Hä? { if(c > 31 ||c=='\r'||c=='\n'||c=='\t'/**/) // was soll das? text[i]^=s[pi]; } if(pi > leng) // pi < leng meinst du wohl pi++; else pi =0; } return text; }
-
Hm, stimmt, macht net soviel sinn.
Hab jetzt ein paar sachen abgeändert.
Er liest jetzt die ganze datei ein, und kann sie auch wieder korrekt speichern.
Allerdings ergibt das verschlüsseln nachwievor zeichensalat.
Devil
-
Funktioniert
Ich hätte die zeichen nicht filtern dürfen,
das war noch aus ner alten version...Devil
-
So, hab jetzt noch einpaar fragen bezüglich Performance :
Den XOR algo kann man wohl net mehr sonderlich optimieren, oder sehe ich da was falsch ?
Bringts evtl. was wenn ich es in eine Membervariable einlese, und so dann
nicht mehr an die Funktion übergeben muss ? (Er braucht bei 400 kb Dateien sehr lange)
Ich schreib die Datei jetzt mit ofstream::write(...), denke das das schnellste ist.
Das einlesen mache ich mit :stringstream tmp; tmp << in.rdbuf(); text = tmp.str();
Kenn mich jetzt nicht aus wie der Compiler das intern übersetzt, ist das die
Schnellste möglichkeit ? Oder ist der weg über stringstream gar ein unnötiger Umweg ?Und was ist schneller (oder kein Unterschied...)
pi < leng ? pi++ : pi =0; //oder if(pi<leng) pi++; else pi =0;
wenn es einen unterschied gibt, tipp ich aufs erste
Devil
[ Dieser Beitrag wurde am 28.05.2003 um 13:20 Uhr von devil81 editiert. ]
-
ubergib ein den string per refernez wenn dein compilier http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=Optimize#Answ nicht kann,
der weg über stringstream dürfte langsammer sein
und ob if oder ?: ist egal,
-
Hm, wie kann ich denn dann die Daten schnell einlesen ?
Bei Getline corrupiert er mir die Datei...Devil
[ Dieser Beitrag wurde am 28.05.2003 um 14:13 Uhr von devil81 editiert. ]
-
Ok, für ne 200 kb Datei braucht er jetzt 4 Sekunden im Release modus,
und 7 im Debug. Auf einem 400 Mhz rechner.
Allerdings hätte ich gerne ne bessere performance, vorschläge sind willkommen.Devil
-
Hab den Quellcode einwenig umgeschrieben. Lese und schreibe jetzt über fstream.
Quellcode:
bool Crypt::cryptfile(std::string path) { fstream file(path.c_str(),ios::in|ios::out|ios::binary);//Datei öffnen if(!file) return false; //Dateigröße feststellen file.seekg(0,ios::end); unsigned long size = streamoff(file.tellg()); file.seekg(0,ios::beg); //Datei in Puffer einlesen char *pcbuffer = new char[size]; file.read(pcbuffer,size); //Daten verschlüsseln int length = passwort.length(), pi =0; for(int i =0; i < size; i++) { pcbuffer[i]^=passwort[pi]; pi < length ? pi++ : pi =0; } //Datei mit Daten schreiben file.seekg(0,ios::beg); file.write(pcbuffer,size); //aufräumen file.close(); delete [] pcbuffer; }
Ein 100 Seiten Worddokument von der Größe 320 KB macht er jetzt in 0.3 Sekunden
Wenn's jemand schneller schafft, bitte posten
Devil