Bitweise Rotation
-
Geiselpeter schrieb:
Hi,
danke für die schnelle Antwort. Nun ist es auch ziemlich einleuchtend, wie es funktioniert. Aber leider klappt es immernoch nicht richtig mit der Rotation. Ich öffne über eine selbstgeschriebene Funbktion z.B eine Textdatei, lese sie dann aus verschlüssel sie, und schreib sie dann wieder in eine andere Textdatei. Aber es klappt so einfach nicht. Ich glaub irgendwie weiß der Compiler nicht, dass er binär etwas verändern soll oder liest die zu verschlüsselnde Datei nicht binär.
Weiß möglicherweise noch jemand Rat??
Greets Torsten
Bei so einer aussgagekräftigen Beschreibung deines Problemes kann man nur raten. Aber öffnest du die Datei binär? ios::binary ist glaube ich das entsprechende flag. Unter Windows kann es nämlich probleme geben, da "\r\n" als "\n" eingelesen wird.
-
Die Textdatei wird binär zum lesen geöffnet und auch zum schreiben binär geöffnet.
Gibt es nicht eine Möglichkeit, wie ich es kontrollieren kann, on die "0" und "1" wirklich verschoben werden??Sorry, dass ich so blöd fragen muss, aber ich bin totaler Anfänger.
Greets
-
Hallo,
so aus dem Bauch heraus wuerd ich sagen, dass du dein Byte mit 0x80 (Dez: 128)
verUNDest und schaust, ob das vorderste Bit gesetzt ist oder nicht. Dann kannst
das irgendwie vermerken und entsprechend handeln. Wenn du z. B. ein links shift
machst, schaust du ob das hoechste Bit gesetzt ist, wenn nicht, normal shiften,
wenn doch, dann shiftest du und verODERst es mit 0x01:01101001 //links shift; hoechstes bit nicht gesetzt -> nur shiften 11010010 //links shift; hoechstes bit ist gesetzt -> shiften 10100100 //mit 0x01 (00000001) verODERn 00000001 10100101 //unser ergebnis
Denke, dass es machbar ist und hoffe, dass mir hier kein Fehler unterlaufen ist.
Denke aber, dass das Prinzip klar ist.mfg
v R
-
Hi,
ich habe mir gedacht ich zeig euch mal den Code, wahrscheinlich wird ein Pro sofort den Fehler sehn:
void encrypt(FILE *fpi, FILE *fpo, const char passw[])
{int i=0;
int rot=1;
char temp;
char c;while ((c = fgetc(fpi)) != EOF){
if (passw[i]=='\0'){
i=0;
rot=rot+1;
if (rot==8)
rot=1;
}
temp=c;
c=c<<rot;
temp = temp>>(8-rot);
c=(temp|c);
c = (c ^ passw[i]);
fputc (c, fpo);
i++;
}}
Das Programm soll bitweise Verschlüsseln(rotierend) und anschließend mit dem Passwort Xor verknüpft werden. Das Gleiche dann natürlich für die Entschlüsselung.
-->void decrypt(FILE *fpi, FILE *fpo, const char passw[])
{int i=0;
int rot=1;
char c;
char temp;while ((c = fgetc(fpi)) != EOF){
if (passw[i]=='\0'){
i=0;
rot=rot+1;
if (rot==8)
rot=1;
}
c = (c ^ passw[i]);
temp=c;
c=c>>rot;
temp = temp<<(8-rot);
c=(temp|c);
fputc (c, fpo);
i++;
}}
-
Das Problem bei der Sache ist meiner Meinung nach das Rotieren von temp. Nach dieser Operation:
temp=temp>>(8-rot);hat temp nämlich überhaupt keinen Wert mehr.
ich weiß einfach nicht worans liegt.
Greets and THX im voraus.
-
Hallo,
dank eingesetzter Codetags hab ich nich so recht die Lust Deinen Source zu testen, aber schau mal hier:
http://c-plusplus.net/forum/viewtopic.php?t=59797&sid=8b65bdf2f9bd070b173b96e98f0e6754
vllt. hilfts weiter
-
Hi Knuddelbär,
mit deinem Hinweis hatte ich es anfangs versucht. Es klappt auch soweit alles nur was macht genau diese Zeile?
--> zeich2 = zeich2<<(unsigned char) ((sizeof(zeich2) << 3) -n);
sie soll soch eigentlich nur den zwischengespeicherten Wert nun um "Groesse - n Stellen" nach rechts verschieben, also sollte es doch der gleiche Befehl sein wie meiner:
--> temp=temp>>(8-rot);Das Links veschieben klappt auch einwandfrei, nur halt das Rechts verschieben nicht. Er hat einfach nichts mehr gepeichert.
Woran könnte es denn noch liegen?
Greets Torsten
-
Na,
wenn das muster:
00001111 ist und Du schiebst nun 4 Bits nach rechts ....
.... da bleibt auch nurnoch 00000000 übrig. Das ist ok.
Es werden nämlich 0 nachgeschoben von links!Es gibt in C++ keine rotierende Methoden. Also schieben wir die sachen und verknüpfen diese später wieder.
Mal Dir das mal auf papier auf was ich da im detail mache... Ich hatte in Assembler viel mit ror rol gemacht und das dann irgendwann portabel in C gebraucht.
Daher das getrickseNoch nen Tip:
#include <bitset>
cout<<bitset<8>(c); // gibt c als Bitmuster aus.
Desweiteren solltest Du darauf achten das Dein Typ unsigned ist. Sonst wird 1 nachgeschoben nicht 0.
Beispiel:
00111100
Die wollen wir um 4 Bits verschieben.
0011 1100
Daraus ergibt sich:
00000011
und
11000000Das mit | cerknüpft ergibt:
11000011
Genau das was wir suchen.
template <class T> T ror(int c,T a) { T t(a<<c); a>>=(sizeof(T)*8) -c; return t|a; }
(sizeof(T)*8) -c;
Rechnet einfach aus wieviele Bits verschoben werden müssen.
sizeof(T) -> größe in Byte
*8 -> größe in Bits
-c -> ergibt wieviele Bits übrig bleiben.
-
Ok THX,
ich probiers nochmal aus. Erstmal vielen Dank für Deine/Eure Hilfe.
Greets Torsten
-
Hi,
das Verfahren hab ich soweit kapiert und auch reingehackt. aber es klappt trotzdem nicht.
das erste Verchieben klappt einwandfrei, nur beim zweiten verschieben oder verodern muss irgendwo der Fehler liegen.
kann einer nochmal bitte nachschauen:
void encrypt(FILE *fpi, FILE *fpo, const char passw[]) { int i=0; int rot=1; unsigned char temp; char c; while ((c = fgetc(fpi)) != EOF){ if (passw[i]=='\0'){ i=0; rot=rot+1; if (rot==8) rot=1; } temp=c; c=c<<rot; temp = temp>>(8-rot); c=(temp|c); //c = (c ^ passw[i]); fputc (c, fpo); i++; } } /********************************************************************* * Name: decrypt * * * * Zweck: Das Programm entschluesselt den Dateiinhalt der * * Quelldatei durch Vertauschung von Bitgruppen variabler * * Breite und speichert diesen in der Zieldatei. * * Die Breite der Bitgruppen wird durch * * Pseudozufallszahlen bestimmt. * * * * Prototyp: void decrypt(FILE *fpi, FILE *fpo); * * * * Parameter: fpi: (E) File-Pointer der Quelldatei * * fpo: (E) File-Pointer der Zieldatei * * key: (E) aus maximal 400 Nutzzeichen bestehender * * Verschluesselungstext * * * * Funktionswert: keinen * * * *********************************************************************/ void decrypt(FILE *fpi, FILE *fpo, const char passw[]) { int i=0; int rot=1; char c; unsigned char temp; while ((c = fgetc(fpi)) != EOF){ if (passw[i]=='\0'){ i=0; rot=rot+1; if (rot==8) rot=1; } //c = (c ^ passw[i]); temp=c; c=c>>rot; temp = temp<<(8-rot); c=(temp|c); fputc (c, fpo); i++; } }
Greets Torsten
-
Beschreib bitte mal im detail wo das Problem liegt.
Der fehler muss da irendwo liegen reicht mir im moment nicht.
Welcher Fehler ?
Was geht nicht ?
-
Also,
1.das gelesene Zeichen in C wird korrekt um "rot" Stellen nach links verschoben. das geespeicherte zeichen in temp (was ich noch zum verOdern brauch) lässt sich z.B. nicht um (8-rot) stellen nach rechts verschieben. wenn ich manuell nach rechts verschiebe, z.B. um 4 Stellen dann macht er es.
2. das verodern nimmt er nicht richtig an. er scheibt immer nur das in C gespeicherte Zeichen in die Datei. also nur das Zeichen, was nach links verschoben wurde.hoffe du kannst damit was anfangen
Greets Torsten
-
nicht um (8-rot) stellen nach rechts verschieben. wenn ich manuell nach rechts verschiebe, z.B. um 4 Stellen dann macht er es.
Wie hast Du das geprüft ?
Was ist temp vor dem schieben ?
Was ist temp nach schieben durch rot-x
Was ist temp nach schieben durch manuell ?
-
Hi,
ich habs mir ausprinten lassen und auch über ein Text-Binär-Wandlungsprogramm die einzelnen Veränderungen angeschaut.
Temp vor dem verschieben ist gleich c --> temp==c also so wies sein soll!
c wird auch korrekt um eine Stelle verschoben habs s.o. geprüft.
nachdem c mit temp verOdert wird ist c aber immernoch gleich c(als hätte ich gar nichts gemacht.)temp lässt sich nicht rotieren um 7stellen (8-1)!
Kontrolle:
01001001 01100011 01101000 --> Ich
10010010 11000110 11010000 --> Ich um eine Stelle nach links rotiert (’ÆÐ) FUNZT
00100000 0010000 000100000 -->Ich um 8-1 Stellen nach rechts rotiert. Ist aber leider falsch!das ist das Problem