Hilfe bei C++ "Verschlüsselungen"

Hmm schon wieder ein Problem...
Habe jetzt soweit alle Funktionen fertig allerdings bekomme ich schon wieder einen "Rate Error".
Villeicht weiß ja trotzdem jemand weiter. Ich poste jetzt mal direkt die ganze Funktion:
C++:
Datei Datei::bFormatieren(Datei datei) {

 char * form="";
 int rot=0;

 for (int i = 0; i < text.length(); i++) {
  rot++;

  if (rot > datei.passwort.length()) {
   rot = 0;
  }

  form += datei.binary[i] ^ datei.passwort[rot];

 }
 datei.binary = form;

 return datei;
}

EDIT: Gut, rate Error ist verschwunden... tippfehler xD. Dafür jetzt ein neues Problem, in die Datei die ich (erfolgreich) einlese, wird etwas komisches reingeschrieben. Hier nochmal die "schreibe Funktion" (die obige habe ich auch hier korrigiert):
C++:
Datei Datei::bSchreiben(Datei datei) {

 std::ofstream quelle;
 quelle.open(datei.dateiPfad, std::ios::out | std::ios::binary);
 if (!quelle) {
  std::cout << "Error1!\n";

 }
 else {
  quelle.write(datei.binary, sizeof(datei.binary));
 }
 datei.binary = "";

 return datei;
}


Beispiel: (.jpg)
Aus: (naja ein Bild halt)
Wird: "kein Bild mehr kanns net öffnen und hat statt 12.000 chars nur noch 4..."

Beispiel: (.txt)
Aus "Hallo!"
Formatiert:"U?"
Wird entformatiert:ؠؠ
 
Zuletzt bearbeitet:
Vollständigkeitshalber jetzt auch noch mal die "lesen Fuktion":
C++:
Datei Datei::binaryLesen(Datei datei) {

 system("cls");
 std::cout << "Passowrt zum ver- oder entschlüsseln eingeben: \n";
 std::cin.ignore();
 std::getline(std::cin, datei.passwort);
 std::cout << "Dein Passowort: " << datei.passwort << "\n";


 std::string zeile;
 std::ifstream quelle;
 quelle.open(datei.dateiPfad, std::ios::binary);
 if (!quelle) {
  std::cout << "Error1!\n";
  system("pause");
 }
 else {
  
  quelle.seekg(0, quelle.end);
  datei.bLength = quelle.tellg();
  quelle.seekg(0, quelle.beg);
  //create platz
  datei.binary = new char[datei.bLength];

  // read data as a block:
  std::cout << "Reading " << datei.bLength << " characters... ";

  quelle.read(datei.binary, datei.bLength);

  if (quelle) {
   std::cout << "all characters read successfully.\n"<<sizeof(datei.binary);
  }
  else {
   std::cout << "error: only " << quelle.gcount() << " could be read";
   quelle.close();
  }

 }

 
 return datei;
}
 

cwriter

Erfahrenes Mitglied
Dein char form funktioniert so nicht.
Ein char* kann nur eine Adresse halten. Bei dir ist diese Adresse jene der Literal Constant "".
Ein += darauf gibt dir schlicht eine Adresse, du baust dadurch keinen String.
Für das, was du willst, wäre ein std::vector<uint_8t> wesentlich besser geeignet als ein char.

Dazu wäre es recht praktisch, auch die gesamte Klasse "Datei" zu kennen. Ich hoffe sehr, dass deine "binary"-Member kein char* ist; denn das würde nicht funktionieren.
/EDIT: OK, wenn du's so machst, geht das. Du müsstest dann aber auch form entsprechend einen Speicherbereich geben (oder einfach direkt in binary hineinschreiben).

Du musst übrigens nicht immer eine Datei zurückgeben, dafür hast du ja die Klasse? (Und wenn du nur den Parameter verändern willst: Referenz).

Gruss
cwriter
 
Hi cwriter!
Das ganze Programm habe ich in 3 Dateien ausgelagert: Header Datei(also Klasse ich poste sie hier rein), Implementierung (die Codeschnipsel) und die main halt(auch sehen?) Mit vectoren habe ich bis jetzt nichts gemacht ist das kurz zu erklären?

Klasse Datei:
C++:
#include <string>

class Datei {
 std::string text;
 std::string passwort;
 char * binary;
 int bLength;

public:
 std::string dateiPfad;
 Datei einlesen(Datei txt);
 Datei formatieren(Datei txt);
 Datei schreiben(Datei txt);
 Datei entFormatieren(Datei txt);

 Datei binaryLesen(Datei txt);
 Datei bFormatieren(Datei txt);
 Datei bSchreiben(Datei txt);
};

Der binary Member ist wohl ein char * :|
 
So, meine formatieren Funktion sieht jetzt so aus:
C++:
Datei Datei::bFormatieren(Datei datei) {
 std::string text=datei.binary;
 int rot=0;

 for (int i = 0; i < text.length(); i++) {
  rot++;
  if (rot > datei.passwort.length()) {
   rot = 0;
  }

  datei.binary[i] = datei.binary[i] ^ datei.passwort[rot];

 }
 return datei;
}

Nun bekomme ich nach formatieren und entformatieren wenigstens das erste Wort zurück... die restlichen fehlen allerdings ... Daraus schließe ich, dass ich irgendwo einen Fehler in der "lesen Funktion" habe...(ist ja oben gepostet ;))
 
Zuletzt bearbeitet:

cwriter

Erfahrenes Mitglied
Mit vectoren habe ich bis jetzt nichts gemacht ist das kurz zu erklären?
Ein std::vector ist ein STL-Container, der Dynamisch wachsen kann und Random Access erlaubt. Im Prinzip ist es ein Array auf dem Heap. Die Klasse übernimmt die Vergrösserung / Verkleinerung nach Bedarf für dich.
C++:
std::vector<int> vec; //Ungefähr int* vec, aber automatisch new bei push_back (NICHT bei []-Indexierung).
vec.push_back(1);
vec.push_back(42);
//vec[0] == 1
//vec[1] == 42
//vec.size() == 2

vec.pop_back();
//vec[0] == 1
//vec.size() == 1

//Ähnlich Strings, aber ohne + und ohne Zeichenbeschränkungen (Strings haben theoretisch auch keine, aber es vermischt sich sehr ins Ungenaue...)
std::string str;
str += 1;
str += 42;

//str[0] == 1
//str[1] == 42
Wichtig: Wie bei allen STL (Standard Template Library) - Klassen, könntest du das auch nachbauen. Es ist aber sehr viel angenehmer, Fertiges zu verwenden (ausser, du willst die letzten Prozente Leistung rausholen).

Der binary Member ist wohl ein char * :|
Du du ihn ja initialisierst, macht das nicht wirklich etwas. Es ist einfach ein bisschen mehr Aufwand. Dann ist es aber komisch, dass du noch einen std::string text hast? Den brauchst du ja eigentlich nicht, wenn du schon einen char* hast, womit du die Daten speicherst?
Text wird ja auch nicht initialisiert? Da du dann text.length() nutzt (welches 0 sein dürfte, frag den Debugger), ver- und entschlüsselst du eigentlich gar nichts.
std::string ist des Weiteren ungeeignet für binäre Daten (dafür gibt es std::vector, bzw. std::string ist ein gepimpter std::vector), daher würde ich nur "binary" benutzen. Da du da aber keine Länge hast, musst du die Länge explizit mitspeichern (neue Membervariable/Funktion).


C++:
datei.binary[i] = datei.binary[i] ^ datei.passwort[rot];
//Lässt sich schreiben als:
datei.binary[i] ^= datei.passwort[rot];

Du übergibst an deine Funktionen immer eine Kopie einer Instanz von Datei, das ist dir schon bewusst, oder?
C++:
Datei Datei::bFormatieren(Datei datei) //Kopie
Datei Datei::bFormatieren(Datei& datei) //Referenz
Bei einer Referenz gibst du nur die Speicheradresse, an der "datei" ist, weiter. Bei einer Kopie kopierst du immer, was zu Problemen führen kann, gerade mit Raw Pointern (void*), da es nur eine Flat Copy, keine Deep Copy ist.

Das ganze Programm habe ich in 3 Dateien ausgelagert: Header Datei(also Klasse ich poste sie hier rein), Implementierung (die Codeschnipsel) und die main halt(auch sehen?)
Du kannst die Dateien sonst einfach zippen und hochladen. (Bitte nicht alles aus VS, nur die Codedateien).

Gruss
cwriter
 
Hi,

Ich sage in meinem code: "string test = datei.binary;". Das hab ich gemacht, weil ich im Code bei "datei.binary" kein "length()" verwenden kann. Stattdessen habe ich jetzt "sizeof(...)" genutzt, nur habe ich es oben nicht mehr geändert. In meinem Code gibt es also keinen String text mehr ;) Was mich außerdem verwirrt: Wenn ich das wort "Mein" verschlüssele mit dem pw "cloud" steht in der verschlüsselten txt ein "!". Wenn ich die Datei weider entschlüssele bekomme ich allerdings weider "Mein". "Mein" hat ja aber 3 Zeichen mehr als ein Ausrufezeichen...?
Also weißt du auch nicht genau woran das liegt? Wenn doch, tut mir leid dass ich dich nicht verstanden habe xD
Danke für den Einblick an Vectoren, ich denke ich suche mir mal eine Seite dazu raus um das mal zu verstehen, und ja das mit der Kopie wusste ich, darum returne ich ja auch immer eine Datei
Die Dateien kann ich mal hochladen, bevorzugst du eine bestimte Seite oder soll ichs auf Irgendeiner hochladen?

PS: Wenn es egal ist, hier schonmal der MediaFire link: https://www.mediafire.com/file/iwbd34vbth8qjfa/cwriter.rar

/EDIT: Habe nochmal was rumprobiert verschlüssung geht ABER: nur die ersten 4 Buchstaben werden verschlüsselt... der rest wird einfach gelöscht :|

PPS: Ach ja noch was wen du dir die Dateien anschaust: Ich weiß, dass die Passwortabfrage ganz am Anfang in der main nichts nützt da man das passowort auch in der kompilierten exe einsehen kann... ich habe das eingebaut damit wenn meine Kollegen oder sonst wer die noch weniger können als ich, nicht bei dem Versuch etwas zu entschlüsseln möglicherweise Dateien unlesbar machen- für mich zumindest ;)

LG
 
Zuletzt bearbeitet:

cwriter

Erfahrenes Mitglied
Die Dateien kann ich mal hochladen, bevorzugst du eine bestimte Seite oder soll ichs auf Irgendeiner hochladen?
Im Forum hier.

Es werden nur die ersten vier Buchstaben geschrieben, weil du ein 32bit-Programm erstellst und sizeof(void*) == sizeof(char*) == 4.
Du kannst mit sizeof nicht die Grösse eines Bereichs bestimmen, der an einer Adresse steht (es gibt Tricks, aber alles Undefine Behavior). Du musst die Grösse entsprechend direkt speichern. Und std::string str = "bla"; liest halt nur bis zur ersten 0.
Wenn ich das wort "Mein" verschlüssele mit dem pw "cloud" steht in der verschlüsselten txt ein "!".
Du solltest keinen Texteditor verwenden (oder Notepad++ und die nichtdruckbaren Zeichen darstellen lassen). Texteditoren wie Editor.exe ignorieren die Nichtdruckbaren einfach. Ein Hexeditor wie HxD wird dir alle Werte anzeigen.

Gruss
cwriter