[Datei-Verschluessler] Wo ist der Fehler?



  • ununterschrieben schrieb:

    schau doch mal mit einem debugger nach, da siehst du sofort was schief läuft.
    tip: strings bestehen nicht aus unsigned chars.

    Hab das nun geaendert und bei Text-Dateien klappt das jetzt ganz gut, glaube ich zumindest...
    Aber wenn ich ein Bild verschluessle/entschluessle, dann kommt irgendwie murgs raus... (aber das Bild kann man komischerweise trotzdem ansehen)

    Bild vor dem verschluesseln
    http://img228.imageshack.us/img228/3413/bild2ss9.jpg

    Bild nach dem verschluesseln/entschluesseln
    http://img175.imageshack.us/img175/3634/bildcr0.jpg

    Der Code sieht jetzt so aus:

    // Verschluesseln
    	for (size_t i=0; i<inhalt.size(); i++)
    	{
    		if (inhalt[i] < 127)
    		{
    			inhalt[i] += 1;
    		}
    		else
    		{
    			inhalt[i] = -127;
    		}
    	}
    
    	// Entschluesseln
    	for (size_t i=0; i<inhalt.size(); i++)
    	{
    		if (inhalt[i] > -127)
    		{
    			inhalt[i] -= 1;
    		}
    		else
    		{
    			inhalt[i] = 127;
    		}
    	}
    

    Warum wird das Bild nicht mehr richtig entschluesselt?
    Muss ja einen Grund geben 🙂

    Gruss
    Cartman



  • Ich würde nicht unbedingt std::string verwenden, da das ein typedef für std::basic_string<char> ist und char sich je nachdem wie signed char oder unsigned char verhält. Vielleicht besser eine weitere Instanziierung des basic_string -Templates...

    Zudem:

    else
            {
                inhalt[i] = -127;
            }
    

    Hier wird ja die Hälfte des Wertebereichs auf eine Zahl abgebildet. So ist die Bijektivität nicht mehr gegeben; wie soll beim Entschlüsseln entschieden werden, welcher ursprünglichen Zahl die -127 entsprochen hat?



  • Nexus schrieb:

    Ich würde nicht unbedingt std::string verwenden, da das ein typedef für std::basic_string<char> ist und char sich je nachdem wie signed char oder unsigned char verhält. Vielleicht besser eine weitere Instanziierung des basic_string -Templates...

    Zudem:

    else
            {
                inhalt[i] = -127;
            }
    

    Hier wird ja die Hälfte des Wertebereichs auf eine Zahl abgebildet. So ist die Bijektivität nicht mehr gegeben; wie soll beim Entschlüsseln entschieden werden, welcher ursprünglichen Zahl die -127 entsprochen hat?

    Also den Anfang deines Posts versteh ich nich ... (bin Anfaenger) 😞 Meinst du damit, dass es nich immer sicher ist, ob char signed oder unsigned ist (bezugelich des strings).

    Zum zweiteren:
    Es ist ja so... Der ASCII-Wert des Zeichens wird immer um 1 erhoeht. Wenn es sich aber um ein Zeichen handelt, dass schon den maximalen Wert hat (127) wird der auf das minimalste (-127) gesetzt ... Beim entschluesseln weiss ich ja dann, dass alle Zeichen die -127 sind vor dem Verschluesseln 127 waren...



  • Eric Cartman schrieb:

    Also den Anfang deines Posts versteh ich nich ... (bin Anfaenger) 😞 Meinst du damit, dass es nich immer sicher ist, ob char signed oder unsigned ist (bezugelich des strings).

    Ja, also C++ kennt die drei verschiedenen Typen:

    char
    signed char
    unsigned char
    

    Ob sich char nun bezüglich des Wertebereichs wie signed oder unsigned verhält, ist implementierungsspezifisch. Deshalb sollte man nicht davon ausgehen, dass der Wertebereich von -128 bis 127 geht.

    Eric Cartman schrieb:

    Es ist ja so... Der ASCII-Wert des Zeichens wird immer um 1 erhoeht. Wenn es sich aber um ein Zeichen handelt, dass schon den maximalen Wert hat (127) wird der auf das minimalste (-127) gesetzt ... Beim entschluesseln weiss ich ja dann, dass alle Zeichen die -127 sind vor dem Verschluesseln 127 waren...

    Klar. Sorry, ich hab da grad nicht durchgeblickt, bin vom falschen Wertebereich ausgegangen... Aber das Minimum wäre dennoch -128. 😉



  • @Nexus
    Ahja, jetzt hab ich es begriffen, thx 🙂 - kann mich auch ganz dunkel daran erinnern, dass das irgendwo auch in meinem C++-Buch besprochen wurde 🙂
    Nur wie loese ich jetzt das Problem, wenn ich will dass mein Code Compiler-unabhaengig funktioniert? Waere ein dynamischer signed char-vector das richtige?

    Uebrigens funktioniert mein Programm jetzt. Musste nur die -127 - Werte mit -128 ersetzen... thx 🙂



  • Nexus schrieb:

    Eric Cartman schrieb:

    Also den Anfang deines Posts versteh ich nich ... (bin Anfaenger) 😞 Meinst du damit, dass es nich immer sicher ist, ob char signed oder unsigned ist (bezugelich des strings).

    Ja, also C++ kennt die drei verschiedenen Typen:

    char
    signed char
    unsigned char
    

    Ob sich char nun bezüglich des Wertebereichs wie signed oder unsigned verhält, ist implementierungsspezifisch. Deshalb sollte man nicht davon ausgehen, dass der Wertebereich von -128 bis 127 geht.

    =>
    nimm std::numeric_limits <char>::max() bzw. std::numeric_limits <char>::min() und schau davor, ob max() und min() makro aus der winapi ausgeschalten ist ^^

    allerdings müsste es mit -128 auch bei nem unsigned typen gehen?!

    bb



  • Ein std::vector<signed char> wäre nicht schlecht, zumal es ja hier nicht um den String als Zeichenkette sondern um den Container von einzelnen Zeichen geht.

    Ansonsten - wenn du die Funktionalität von std::string benötigst - kannst du wie gesagt das Template einsetzen:

    typedef std::basic_string<signed char> SignedString;
    

    @ unskilled
    Ich bin mir nicht mehr ganz sicher, aber ich dachte, die Umwandlung negativer Zahlen zu unsigned wäre auch implementierungsspezifisch... Irgendwie kann man sich ja auf nichts wirklich verlassen. 😉

    Das mit numeric_limits finde ich unnötig, da man gleich signed char nehmen kann, um sicher zu gehen.



  • ich würde bei datei und vector bei char bleiben und nur beim rechnen casten.

    for (size_t i=0; i<inhalt.size(); i++) 
        { 
            unsigned char x=inhalt[i];
            ++x;
            inhalt[i]=x; 
        }
    


  • Nimm std::vector<unsigned char> und lass das if-Konstrukt weg. Ein Überlauf führt zum gleichen Ergebnis, egal was für einen Wertebereich du hast.



  • Okay, also ob ich std::basic_string<signed char> oder std::vector<signed char> nehme spielt also keine Rolle oder?

    @Ueberlaeufer
    Sicher? Gilt das auch fuer alle Compiler/Plattformen?

    Ich bin jetzt noch etwas verwirrt wegen char ...
    Warum gibt es signed char und unsigned char ???
    Waere 256 nicht dasselbe Zeichen wie -1?
    Und ich bin mir jetzt noch wegen des einlesens von der Datei unsicher... Wird das Zeichen immer als signed eingelesen? (mit fileobject.get() )

    😕



  • Eric Cartman schrieb:

    Sicher? Gilt das auch fuer alle Compiler/Plattformen?

    Ja, aber nur für vorzeichenlose Typen.


Anmelden zum Antworten