2013-03-26 3 views
5

Ich habe eine Binärdatei, die als Zeichen eingelesen wird. Jedes Zeichen wurde um eine unbekannte Anzahl von Malen nach links verschoben (unter der Annahme mit Umbruch) von jemand anderem. Ich möchte in der Lage sein, jedes Zeichen einzulesen und dann die Verschiebung nach rechts zu bewegen (die Anzahl der Verschiebungen, die ich vermute, muss manuell ermittelt werden, weil ich keinen anderen Weg gefunden habe).Bit verschiebt ein Zeichen mit Wrap? C++

Also, meine aktuelle Idee ist, dass ich in einem Zeichen zu lesen, eine Kopie mit Temp erstellen und dann XOR verwenden:

char letter; //will hold the read in letter 
char temp;  //will hold a copy of the letter 
while(file.read(&letter, sizeof(letter)) //letter now holds 00001101 
{ 
    temp = letter; //temp now holds 00001101 
    letter >>= 1; //shift 1 position to the right, letter now holds 00000110 
    temp <<= 7;  //shift to the left by (8-1), which is 7, temp now holds 10000000 
    letter ^= temp; //use XOR to get the wrap, letter now holds 10000110 
    cout << letter; 
} 

Das Gefühl in meinem erschöpften Kopf macht, aber es funktioniert nicht .. Und ich kann nicht verstehen warum. Größe von Char ist 1 Byte, also dachte ich, ich muss nur mit 8 Bits herumspielen.

Jede Hilfe wäre willkommen.

BEARBEITEN: Gelöst. Vielen Dank an alle. Liebe diese Gemeinschaft zu Tode, ihr seid großartig!

+0

Sie‘ Sie haben uns gesagt, was Sie erwarten - was bekommen Sie eigentlich? –

+0

@sftrabbit Irgendein kryptisches Durcheinander. –

+0

Sie lesen zweimal in 'letter' zweimal pro Schleife und verwerfen den zuerst gelesenen Wert – jthill

Antwort

10

Achten Sie auf die Signifikanz eines Zeichens. Auf vielen Systemen ist es signiert. So ist Ihr letter >>= 1 Zeichen, das die Schicht füllt.

Rotierende ganzen Zahlen in der Regel wie folgt durchgeführt wird

letter = ((unsigned char)letter >> 1) | (letter << 7); 

Wie Mark in den Kommentaren weist darauf hin, können Sie entweder OR | oder XOR ^ verwenden.

+1

BOOM! Das hat mein Freund geklappt! Ich danke dir sehr. Ich habe den bearbeiteten Code nicht verwendet, aber ich werde es versuchen. Was ich getan habe, wurde in einem Char mit einem unsignierten Char gelesen und es wirkte wie ein Zauber. Vielen Dank für das Hinweis auf das unsignierte Ding ... kann nicht glauben, dass ich es verpasst habe. –

+0

Wenn keine überlappenden Bits vorhanden sind, werden 'oder' und' xor' die gleichen Ergebnisse liefern. –

+0

@MarkRansom Sie haben Recht. Das kam mir nicht einmal in den Sinn. – Kyurem

0

Die Anweisung temp <<= 7 verliert die Bits, die Sie umbrechen möchten. Sie müssen die Verschiebung jeweils um ein Bit nach links verschieben. Überprüfen Sie zuerst das höchstwertige Zeichenbit und setzen Sie es vor der Verschiebung auf das rechte Bit.

+0

temp wird um 7 nach links verschoben, weil der Buchstabe einmal nach rechts verschoben wird. Wenn ich bei beiden XOR benutze, gibt es mir das Teil, das auf der rechten Seite abgelegt wurde (und jetzt ist es auf der linken Seite, umwickelt). –

0

ich geneigt sein, würde einen größeren Integral-Typen zu verwenden.

unsigned val = (unsigned)letter & 0xFF; 
val |= val << 8; 

Jetzt müssen Sie nur noch Werte verschieben in val, ohne zusätzlichen Code, um die High-Bits zurück in einzuwickeln