[C++] FStream char Binär ausgeben in Datei



  • Hi Leute,

    ich möchte einen kleinen Converter schreiben, welcher meine .txt datei in eine .pmm Datei verwandelt.
    Die .pmm Datei soll in Binär lesbar sein.
    Doch egal wie ich es drehe und wende, ich bekomme jedesmal nur text in die Datei und keine Binärzeichen oder sonstiges.
    Zudem erhalte ich immer Japanische Zeichen in der Datei.

    Hier mal mein Code:

    #include <iostream>
    #include <string>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
        string DatName;
        char input[30];
    
    	cout << "Dateiname: ";
    	cin  >> DatName;
    
    	ifstream dat (DatName + ".txt", ios::in);
    	ofstream dat2 (DatName + ".pmm", ios::out, ios::binary);
    
    	if (dat == NULL)
    	{
    		cout << "Datei konnte nicht geoeffnet werden." << endl;
    		system ("Pause");
    		return (1);
    	}
    
    	while (true)    
    	{
    		if(!(dat.getline(input, sizeof(input))))
    		break;
    		else
    		{
    				cout << input << endl;
    				dat2.write(input, sizeof(input));
    		}
    	}
    	dat.close ();
    	PacManMap.close();
    
    	system ("Pause");
        return (0);
    }
    

    Weiß jemand woran das liegt und kann mir helfen?

    Mit freundlichem Gruß
    xXSlayerXx



  • TL;DR. Hilft das hier vielleicht?



  • Ne hilft mir nicht weiter.

    Das Programm spukt mir alles in Deutschen zeichen aus und keinen Binärcode.



  • Naja, schon mal versucht, das pmm File in einem Hexeditor zu öffnen?



  • Worin soll sich denn eine binäre von einer Textdatei unterscheiden, wenn sie nur "Text" enthält?



  • Sie soll ja ebend keinen Text enthalten

    also angenommen Input hat den wert "1".
    Dann steht in der Output Datei auch "1" und nicht "è" (Was ein Editor sonst so ausspruckt, wenn er Binärcode liest".

    Also ist der Output fehlerhaft, obwohl ich das Flag ios::binary gesetzt habe.



  • Das zeigt, dass du keine Ahnung hast und nochmal die Antworten auf Stackoverflow lesen solltest, die ich verlinkt habe, denn genau da wirst du auch sehen, wieso du was anderes rausbekommst als erwartet.



  • xXSlayerXx schrieb:

    ich möchte einen kleinen Converter schreiben, welcher meine .txt datei in eine .pmm Datei verwandelt.

    Suche .pmm in Google, so findest Du außer 'Parts per Million' Pegasus Mail Mailbox File - dieses scheint aber ein ASCII-Format zu haben 😕
    Informiere uns doch bitte, wo das Format eines .pmm-File beschrieben ist.

    xXSlayerXx schrieb:

    Die .pmm Datei soll in Binär lesbar sein.

    man kann JEDE Datei 'in Binär' lesen!

    xXSlayerXx schrieb:

    Zudem erhalte ich immer Japanische Zeichen in der Datei.

    kann nicht sein, da Du nur char -Streams (und kein wchar_t ) verwendest. Verwechselst Du das Yen-Symbol ¥ (Code 0xA5) mit Japanischen Zeichen?



  • Kenner des Unicode schrieb:

    Informiere uns doch bitte, wo das Format eines .pmm-File beschrieben ist.

    er meint Portable Bitmap!

    Christian Ivicevic schrieb:

    Das zeigt, dass du keine Ahnung hast und nochmal die Antworten auf Stackoverflow lesen solltest, die ich verlinkt habe, denn genau da wirst du auch sehen, wieso du was anderes rausbekommst als erwartet.

    Das wird wohl nicht reichen

    Hallo xXSlayerXx,
    was denkst Du denn, was Dein Programm tut? Und was meinst Du, was das ist, was in einer Datei steht - so im Allgemeinen?



  • Ich glaube *.pmm steht für PacManMap.

    xXSlayerXx schrieb:

    PacManMap.close();
    

    🙄



  • Das ist schon nicht ganz falsch^^
    Hatte den Code etwas umgeschrieben für das Forum, aber anscheinend etwas vergessen^^

    Ich denke das da einiges falsch rübergebracht und/oder falsch verstanden wurde.

    Also nochmal von anfang an.

    Ich habe mir ein eigenes Format geschrieben mit der Endung (.pmm)[Wie bereits erwähnt, steht dies für PacManMap]

    Nun möchte ich, damit nicht jedes Textprogramm die Datei lesen kann diese in Binärcode übersetzten.

    Das ganze soll so Funktionieren:
    1.Ich gebe den namen meiner .txt Datei an.(z.B. Map.txt)
    2.Das Programm liest diese Datei ein.
    3.Das Programm erstellt eine Datei mit dem Name Map.pmm.
    4.Das Programm schreibt den Inhalt von Map.txt in Binärform in die Datei Map.pmm.

    Beispiel des Aufbaus der .txt Datei:
    X X X X X X X
    X C C C C C X
    X C X X X C X
    X C C C C C X
    X X X X X X X

    Diese Datei kann mein Spiel dann einlesen und je nach Buchstaben angeben, welches Modell geladen werden soll.

    so die Theorier.

    Das ist doch möglich oder vertue ich mich da bei dem Begriff binär?
    Antworten wären super

    MfG
    xXSlayerXx


  • Mod

    xXSlayerXx schrieb:

    Nun möchte ich, damit nicht jedes Textprogramm die Datei lesen kann diese in Binärcode übersetzten.

    STOPP!

    Das ist doch möglich oder vertue ich mich da bei dem Begriff binär?

    Ja, du vertust dich.

    Binär ist keine zauberhafte Verschlüsselung. Nicht-Binärmodus (bei Dateien) heißt einfach nur, dass (unter Windows) die Sequenz "\r\n" zu "\n" wird (beim Lesen) und umgekehrt. Binärmodus heißt, dass diese Konvertierung nicht durchgeführt wird.

    Es gibt auch noch eine zweite Bedeutung des Wortes, dass du zum Beispiel

    ofstream file("foo");
    int i =123;
    file.write(reinterpret_cast<char*>(&i), sizeof(int));
    

    benutzen kannst, damit der Wert 123 nicht als die Zeichenfolge "123" geschrieben wird, sondern in Form der internen Darstellung im Computer (die für Menschen einigermaßen unlesbar ist). Hier findet sich aber auch schon ein kleiner Hinweis, was bei dir nicht so funktioniert, wie du denkst: reinterpret_cast<char*>. Eine Datei ist immer noch eine Ansammlung von Zeichen. Wenn du die interne Repräsentation des Integers in die Datei schreibst, sind das irgendwelche wirren Zeichen. Wenn du die interne Repräsentation deiner Zeichen in eine Datei schreibst, sind das auch Zeichen. Aber immer noch die gleichen! Denn die interne Darstellung eines chars in Form von chars ist natürlich der char selber.

    Da wir nun aber wissen, was dein eigentliches Vorhaben ist:

    Nun möchte ich, damit nicht jedes Textprogramm die Datei lesen kann diese in Binärcode übersetzten.

    (Hier liegt übrigens ein sogenanntes xy-Problem vor: wieso hast du das nicht gleich gefragt?)
    Du suchst also irgendeine Art einfache Verschlüsselung als Sichtschutz. Zwei Feststellungen:
    1. Brauchst du das wirklich? Prinzipiell kann jede Verschlüsselung trivial geknackt werden, da der Schlüssel in deinem Programm stehen muss. Das heißt, jemand, der es wirklich möchte, kann relativ einfach deine Verschlüsselung umgehen. Und jemand, der dies nicht möchte, wird es wahrscheinlich ohnehin nicht interessieren, was in deinen Dateien steht
    2. Eine supereinfacher monoalphabetischer Chiffre wird hier wenig nutzen, da die Struktur der Daten immer noch deutlich erkennbar wäre.

    Falls du 1. bejahst, dann folgt aus 2., dass du keine ganz triviale Verschlüsselung nehmen kannst. Ich empfehle daher ein Verfahren der klassischen Kryptografie: Diese sind sehr einfach zu implementieren und der Aufwand für moderne Verfahren, lohnt sich wegen der in Punkt 1 beschriebenen Probleme nicht. Außerdem ist die Implementierung in der Regel ganz interessant und lehrreich. Für dich wäre vielleicht etwas:
    http://en.wikipedia.org/wiki/Transposition_cipher
    oder
    http://en.wikipedia.org/wiki/Vigenère_cipher



  • @SeppJ: Kleine Korrektur:

    ASCII-Modus (bei Dateien) heißt einfach nur, ...



  • ok das verstehe ich.
    Ich denke ich werde mich später nochmal mit diesem Thema beschäftigen.
    Wahrscheinlich ist es nicht besonders wichtig ist, dass die Datei verschlüsselt ist.
    Ich dachte mir nur, dass das über das Flag ios::binary ganz leicht wäre.

    Aber das was du da schreibst ist schon verständlich. Soetwas in der Art hatte ich mir auch gedacht.

    Deswegen konnte ich einen Integer so Anzeigen, wie ich es mochte, doch eine char nicht.

    Danke für die erklärung.


  • Mod

    Caligulaminus schrieb:

    @SeppJ: Kleine Korrektur:

    ASCII-Modus (bei Dateien) heißt einfach nur, ...

    Natürlich. Danke. Korrigiert.



  • Wenn du eine Datei "schützen" willst, kannst du eine einfache XOR-Verschlüsselung nutzen:

    struct Encryptor {
        char m_bKey;
        Encryptor(char bKey) : m_bKey(bKey) {}
        char operator()(char bInput) {
            return bInput ^ m_bKey++;
        }
    };
    

    Das Verschlüsseln funktioniert mit einem beliebigen "Key" - in meinem Beispiel mit 42, was in Hex 0x2A entspricht:

    std::ifstream input("in.plain.txt", std::ios::binary);
    std::ofstream output("out.encrypted.txt", std::ios::binary);
    std::transform(
        std::istreambuf_iterator<char>(input),
        std::istreambuf_iterator<char>(),
        std::ostreambuf_iterator<char>(output),
        Encryptor(0x2a));
    

    Das ganze kann genialerweise analog rückgängig gemacht werden, da eben Bits bijektiv manipuliert werden:

    std::ifstream input2("out.encrypted.txt", std::ios::binary);
    std::ofstream output2("out.decrypted.txt", std::ios::binary);
    std::transform(
        std::istreambuf_iterator<char>(input2),
        std::istreambuf_iterator<char>(),
        std::ostreambuf_iterator<char>(output2),
        Encryptor(0x2a));
    

    Bitte bedenke aber, dass das eben nicht allzu sicher ist, weil jemand, der an deine Daten kommen will da rankommen wird. Egal mit welchen Mitteln. Es beruhigt aber bisschen das Gewissen, wenn man weiß, dass man seine Daten nicht allzu offenlegt, falls nicht gewünscht.


  • Mod

    XOR-Verschlüsselung:
    Das Problem ist hierbei jedoch (was wahrscheinlich nicht ganz im Sinne des Threaderstellers ist), dass es in dieser Form ein monoalphabetischer Chiffre ist. Daher wird aus einem Plaintext wie

    XXXXXXXXXXXX
    X    X     X
    X    X     X
    X    X     X
    XXXXXXXXXXXX
    

    so etwas wie

    %%%%%%%%%%%%a%6666%66666%a%6666%66666%a%6666%66666%a%%%%%%%%%%%%a
    

    , was mit der richtigen Zeilenbreite im Editor wieder recht lesbar wird:

    %%%%%%%%%%%%a
    %6666%66666%a
    %6666%66666%a
    %6666%66666%a
    %%%%%%%%%%%%a
    

    Man müsste daher mehr als ein Zeichen als Schlüssel nehmen (das wäre dann vom Prinzip ziemlich ähnlich zur Vigenère-Verschlüsselung) oder als Schlüssel den Seed eines PRNGs mit fester Implementierung benutzen (Dann wird's wieder kompliziert).



  • SeppJ, da hast du definitiv Recht. Bisher hatte ich nicht direkt das Problem, weil ich tatsächlich ein eigenes Archiv im Binärformat so verschlüssel. Aber hier ist für solche Fälle definitiv was komplizierteres nötig, was dann in den meisten Fällen dann unnötig ist. Alternativ fallen mir Checksums für verschlüsselte Daten dann ein, um wenigstens eine Manipulation zu verändern, aber diese Checksum muss dann auch wieder irgendwo stehen, was wieder ausgelesen werden kann und ... well, fuck this shit.


Log in to reply