[Datei-Verschluessler] Wo ist der Fehler?
-
Hallo.
Ich hab mir heut ein kleines Programm gebastelt, dass Dateien verschluesselt und auch wieder entschluesselt. Leider klappt das aber nur teilweise. Bestimmte Zeichen werden anscheinend falsch verschluesselt oder entschluesselt.inhalt ist ein
stringin der der gesamte Dateiinhalt enthalten ist.Verschluessler:
for (size_t i=0; i<inhalt.size(); i++) { if (inhalt[i] < 255) { inhalt[i] += 1; } else { inhalt[i] = 0; } }Entschluessler:
for (size_t i=0; i<inhalt.size(); i++) { if (inhalt[i] > 0) { inhalt[i] -= 1; } else { inhalt[i] = 255; } }Wo ist nur der Fehler?
Gruss,
Cartman
-
schau doch mal mit einem debugger nach, da siehst du sofort was schief läuft.
tip: strings bestehen nicht aus unsigned chars.
-
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.jpgBild nach dem verschluesseln/entschluesseln
http://img175.imageshack.us/img175/3634/bildcr0.jpgDer 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::stringverwenden, da das eintypedeffürstd::basic_string<char>ist undcharsich je nachdem wiesigned charoderunsigned charverhält. Vielleicht besser eine weitere Instanziierung desbasic_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::stringverwenden, da das eintypedeffürstd::basic_string<char>ist undcharsich je nachdem wiesigned charoderunsigned charverhält. Vielleicht besser eine weitere Instanziierung desbasic_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 charsignedoderunsignedist (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 charsignedoderunsignedist (bezugelich des strings).Ja, also C++ kennt die drei verschiedenen Typen:
char signed char unsigned charOb sich
charnun bezüglich des Wertebereichs wiesignedoderunsignedverhä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 charsignedoderunsignedist (bezugelich des strings).Ja, also C++ kennt die drei verschiedenen Typen:
char signed char unsigned charOb sich
charnun bezüglich des Wertebereichs wiesignedoderunsignedverhä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::stringbenö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 zuunsignedwäre auch implementierungsspezifisch... Irgendwie kann man sich ja auf nichts wirklich verlassen.
Das mit
numeric_limitsfinde ich unnötig, da man gleichsigned charnehmen 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>oderstd::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 essigned charundunsigned 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 alssignedeingelesen? (mitfileobject.get())
-
Eric Cartman schrieb:
Sicher? Gilt das auch fuer alle Compiler/Plattformen?
Ja, aber nur für vorzeichenlose Typen.