Binäres Schreiben/Lesen mittels fstream!

mowl

Mitglied
Ich habe eine kleine Verschlüsselung geschrieben, das ganze basiert darauf, dass die ASC II Tabelle vertauscht wird.
Das Verschlüsseln ist kein Problem und auch das Entschlüsseln funktioniert einwandfrei, aber nur bei Textdateien.
"Binärdateien" werden nicht vollständig eingelesen, trotz ios::binary.
Verschlüsseln:
Code:
#include <string>
#include <fstream>
#include <cstdlib>

using namespace std;

int main(int argc, char *argv[])
{
    int chars[] = {106, 123, 238, 135, 24, 107, 194, 195, 158, 80, 136, 91, 81, 168, 227, 174, 22, 44, 73, 26, 131, 219, 105, 15, 129, 62, 221, 32, 191, 10, 170, 171, 233, 180, 28, 8, 5, 98, 240, 149, 176, 95, 199, 16, 60, 113, 228, 118, 11, 109, 9, 127, 177, 115, 93, 41, 205, 250, 75, 218, 49, 7, 220, 193, 90, 155, 188, 1, 145, 254, 35, 241, 20, 247, 27, 46, 175, 86, 84, 159, 248, 222, 237, 160, 71, 103, 117, 165, 161, 17, 236, 139, 151, 99, 57, 217, 54, 42, 40, 89, 153, 83, 201, 209, 156, 104, 78, 19, 33, 167, 111, 154, 55, 121, 239, 230, 66, 190, 47, 65, 70, 235, 164, 137, 210, 101, 231, 112, 148, 200, 134, 225, 77, 92, 198, 242, 197, 88, 172, 147, 67, 122, 36, 72, 69, 138, 211, 76, 252, 223, 186, 82, 163, 152, 202, 96, 31, 207, 214, 108, 58, 249, 85, 34, 68, 189, 23, 245, 48, 213, 157, 184, 12, 133, 39, 212, 179, 162, 14, 144, 30, 2, 234, 166, 25, 97, 53, 224, 43, 50, 185, 246, 94, 203, 59, 206, 13, 37, 187, 6, 178, 169, 216, 208, 21, 130, 61, 126, 3, 150, 226, 140, 232, 244, 251, 143, 125, 100, 229, 63, 120, 74, 173, 52, 128, 196, 146, 132, 192, 29, 141, 204, 124, 45, 4, 110, 243, 51, 255, 114, 87, 64, 102, 142, 181, 215, 183, 116, 182, 56, 38, 119, 253, 18, 79};

    char str[4096];
    string contents;
    ifstream in(argv[1], ios::in | ios::binary);
    
    while (in) {
        in.getline(str, 4096);
        contents += str;
        contents += "\n";
    }
    in.close();
   
    string crypt;
    int i;

    // content.size() - 2, weil EOF und \n weg muessen
    for (i = 0; i < contents.size() - 2; i++) {
        crypt += (unsigned char)chars[(unsigned char)contents[i]];
    }

    ofstream out(argv[1], ios::out | ios::binary);
    out.write(crypt.c_str(), crypt.size());
    out.close();

    return 0;
}
Entschlüsseln:
Code:
#include <string>
#include <fstream>
#include <cstdlib>

using namespace std;

int main(int argc, char *argv[])
{
    int chars[] = {106, 123, 238, 135, 24, 107, 194, 195, 158, 80, 136, 91, 81, 168, 227, 174, 22, 44, 73, 26, 131, 219, 105, 15, 129, 62, 221, 32, 191, 10, 170, 171, 233, 180, 28, 8, 5, 98, 240, 149, 176, 95, 199, 16, 60, 113, 228, 118, 11, 109, 9, 127, 177, 115, 93, 41, 205, 250, 75, 218, 49, 7, 220, 193, 90, 155, 188, 1, 145, 254, 35, 241, 20, 247, 27, 46, 175, 86, 84, 159, 248, 222, 237, 160, 71, 103, 117, 165, 161, 17, 236, 139, 151, 99, 57, 217, 54, 42, 40, 89, 153, 83, 201, 209, 156, 104, 78, 19, 33, 167, 111, 154, 55, 121, 239, 230, 66, 190, 47, 65, 70, 235, 164, 137, 210, 101, 231, 112, 148, 200, 134, 225, 77, 92, 198, 242, 197, 88, 172, 147, 67, 122, 36, 72, 69, 138, 211, 76, 252, 223, 186, 82, 163, 152, 202, 96, 31, 207, 214, 108, 58, 249, 85, 34, 68, 189, 23, 245, 48, 213, 157, 184, 12, 133, 39, 212, 179, 162, 14, 144, 30, 2, 234, 166, 25, 97, 53, 224, 43, 50, 185, 246, 94, 203, 59, 206, 13, 37, 187, 6, 178, 169, 216, 208, 21, 130, 61, 126, 3, 150, 226, 140, 232, 244, 251, 143, 125, 100, 229, 63, 120, 74, 173, 52, 128, 196, 146, 132, 192, 29, 141, 204, 124, 45, 4, 110, 243, 51, 255, 114, 87, 64, 102, 142, 181, 215, 183, 116, 182, 56, 38, 119, 253, 18, 79};

    char str[4096];
    string contents;
    ifstream in(argv[1], ios::in | ios::binary);
  
    while (in) {
        in.getline(str, 4096);
        contents += str;
        contents += "\n";
    }
    in.close();

    string crypt;
    int i, x;

    // content.size() - 2, weil EOF und \n weg muessen
    for (i = 0; i < contents.size() - 2; i++) {
        for (x = 0; x < 255; x++) {
            if (chars[x] == (unsigned char)contents[i]) {
                crypt += (unsigned char)x;
                break;
            }
        }
    }

    ofstream out(argv[1], ios::out | ios::binary);
    out.write(crypt.c_str(), crypt.size());
    out.close();

    return 0;
}
Wenn weitere Infos/Erklärungen benötigt werden dann bitte melden´.
Vielen Dank für jeden hilfreichen Post.
 
Code:
 while (in) {
        in.getline(str, 4096);
        contents += str;
        contents += "\n";
    }
wenn du binär arbeitest kannst du nicht weiter so mit Strings arbeiten !
Denk doch einfach nach was passiert sobald eine \0 in den binären Daten ist.
Du musst ein einfaches Array verwenden und den ganzen "Schmu" mit den Strings rauswerfen.

Diese Frage/Problem wurde übrigens schon recht oft gestellt, glaub Platz zwei nach das Konsolenfenster schließt sich immer ;)

Falls weitere Fragen vorhanden sind nicht scheuen diese zu stellen !
 
Ja ich hab mir das schon gedacht, aber ist es nicht das selbe, wenn ich eine Nullterminierte Zeichenkette alloziiere? Dann kann ich doch auch string verwenden oder?
Kannst du einen Thread mit der Lösung posten bzw. mir sagen wie ich es ohne string machen müsste? In der Suche finde ich leider nichts passendes bzw. garnichts.
 
mach dir halt ein char Array und lese die Daten binär ein !

Das Problem ist das in einer Datei doch recht oft Nullen vorkommen können und diese mit Strings nicht gut zu handhaben.
 
Ja danke ich habe es jetzt auch per read() gelöst:
Verschlüsseln:
Code:
#include <fstream>
#include <cstdlib>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    int chars[] = {106, 123, 238, 135, 24, 107, 194, 195, 158, 80, 136, 91, 81, 168, 227, 174, 22, 44, 73, 26, 131, 219, 105, 15, 129, 62, 221, 32, 191, 10, 170, 171, 233, 180, 28, 8, 5, 98, 240, 149, 176, 95, 199, 16, 60, 113, 228, 118, 11, 109, 9, 127, 177, 115, 93, 41, 205, 250, 75, 218, 49, 7, 220, 193, 90, 155, 188, 1, 145, 254, 35, 241, 20, 247, 27, 46, 175, 86, 84, 159, 248, 222, 237, 160, 71, 103, 117, 165, 161, 17, 236, 139, 151, 99, 57, 217, 54, 42, 40, 89, 153, 83, 201, 209, 156, 104, 78, 19, 33, 167, 111, 154, 55, 121, 239, 230, 66, 190, 47, 65, 70, 235, 164, 137, 210, 101, 231, 112, 148, 200, 134, 225, 77, 92, 198, 242, 197, 88, 172, 147, 67, 122, 36, 72, 69, 138, 211, 76, 252, 223, 186, 82, 163, 152, 202, 96, 31, 207, 214, 108, 58, 249, 85, 34, 68, 189, 23, 245, 48, 213, 157, 184, 12, 133, 39, 212, 179, 162, 14, 144, 30, 2, 234, 166, 25, 97, 53, 224, 43, 50, 185, 246, 94, 203, 59, 206, 13, 37, 187, 6, 178, 169, 216, 208, 21, 130, 61, 126, 3, 150, 226, 140, 232, 244, 251, 143, 125, 100, 229, 63, 120, 74, 173, 52, 128, 196, 146, 132, 192, 29, 141, 204, 124, 45, 4, 110, 243, 51, 255, 114, 87, 64, 102, 142, 181, 215, 183, 116, 182, 56, 38, 119, 253, 18, 79};

    ifstream in(argv[1], ios::in | ios::binary);
    in.seekg(0, ios::end);
    int filesize = in.tellg();

    in.seekg(0, ios::beg);
    char contents[filesize];
    char text[filesize];

    in.read(contents, filesize);
    in.close();

    int i;
    for (i = 0; i < strlen(contents); i++) {
        text[i] = (unsigned char)chars[(unsigned char)contents[i]];
    }

    fstream out(argv[1], ios::out | ios::binary);
    out.write(text, filesize);
    out.close();

    return 0;
}
Entschlüsseln:
Code:
#include <fstream>
#include <cstdlib>

using namespace std;

int main(int argc, char *argv[])
{
    int chars[] = {106, 123, 238, 135, 24, 107, 194, 195, 158, 80, 136, 91, 81, 168, 227, 174, 22, 44, 73, 26, 131, 219, 105, 15, 129, 62, 221, 32, 191, 10, 170, 171, 233, 180, 28, 8, 5, 98, 240, 149, 176, 95, 199, 16, 60, 113, 228, 118, 11, 109, 9, 127, 177, 115, 93, 41, 205, 250, 75, 218, 49, 7, 220, 193, 90, 155, 188, 1, 145, 254, 35, 241, 20, 247, 27, 46, 175, 86, 84, 159, 248, 222, 237, 160, 71, 103, 117, 165, 161, 17, 236, 139, 151, 99, 57, 217, 54, 42, 40, 89, 153, 83, 201, 209, 156, 104, 78, 19, 33, 167, 111, 154, 55, 121, 239, 230, 66, 190, 47, 65, 70, 235, 164, 137, 210, 101, 231, 112, 148, 200, 134, 225, 77, 92, 198, 242, 197, 88, 172, 147, 67, 122, 36, 72, 69, 138, 211, 76, 252, 223, 186, 82, 163, 152, 202, 96, 31, 207, 214, 108, 58, 249, 85, 34, 68, 189, 23, 245, 48, 213, 157, 184, 12, 133, 39, 212, 179, 162, 14, 144, 30, 2, 234, 166, 25, 97, 53, 224, 43, 50, 185, 246, 94, 203, 59, 206, 13, 37, 187, 6, 178, 169, 216, 208, 21, 130, 61, 126, 3, 150, 226, 140, 232, 244, 251, 143, 125, 100, 229, 63, 120, 74, 173, 52, 128, 196, 146, 132, 192, 29, 141, 204, 124, 45, 4, 110, 243, 51, 255, 114, 87, 64, 102, 142, 181, 215, 183, 116, 182, 56, 38, 119, 253, 18, 79};

    ifstream in(argv[1], ios::in | ios::binary);
    in.seekg(0, ios::end);
    int filesize = in.tellg();

    in.seekg(0, ios::beg);
    char contents[filesize];
    char text[filesize];

    in.read(contents, filesize);
    in.close();

    int i, x;

    for (i = 0; i < strlen(contents); i++) {
        for (x = 0; x < 255; x++) {
            if (chars[x] == (unsigned char)contents[i]) {
                text[i] = (unsigned char)x;
                break;
            }
        }
    }

    fstream out(argv[1], ios::out | ios::binary);
    out.write(text, filesize);
    out.close();

    return 0;
}
Das einlesen klappt, aber da im String mehrere \0 sind werden zu wenige Zeichen eingelesen, weil die char Arrays mit \0 nicht umgehen können.
Wie könnte ich das jetzt lösen?
 
codieren und decodieren musst du natürlich auch auf Zahlen und nicht Strings machen und dann stören auch keine Nullen wenn deine Funktion umkehrbar ist !
 
Zurück