move_slow_break_things
move_slow_break_things

Reputation: 847

C++- Reverse bits in hex

I want to be able to reverse the bits stored at a memory address (in hex). So for example, 0xABCD -> 0xDCBA

I have looked at other solutions online and they all involve complex bit manipulation and I wanted to see if there was a way to do it using string representations.

So I want to convert 0xABCD to "0xABCD". Reverse this string (which I know how to do) and then convert "0xDCBA" to 0xDCBA.

Complete newbie at C++ so I'm a bit lost and other similar questions haven't really helped.

Upvotes: 1

Views: 2921

Answers (2)

Chris Dodd
Chris Dodd

Reputation: 126253

Do you want to reverse the bits (binary digits) or do you want to reverse the hex digits? You contradict yourself.

0xABCD is binary 1010101111001101, so reversing the bits would be 1011001111010101, which is 0xB3D5.

In general, to reverse digits (in any base) you need to extract the digits, reverse them, and then repack them. Computers use binary internally, so reversing digits in any power-of-2 base is relatively easy -- you just shift and mask them to extract and shift and bitwise-or them to recombine.

unsigned reverse16binary(unsigned val) {
    /* reverse bits in a 16-bit binary number */
    unsigned rv = 0;
    for (int bit = 0; bit < 16; bit++) {
        int digit = (val >> bit) & 1;  // extract a digit
        rv |= digit << (15 - bit);   // stick it in the result
    }
    return rv;
}

unsigned reverse16hex(unsigned val) {
    /* reverse hex digits in a 16-bit binary number */
    unsigned rv = 0;
    for (int bit = 0; bit < 16; bit += 4) {
        int digit = (val >> bit) & 0xf;  // extract a digit
        rv |= digit << (12 - bit);   // stick it in the result
    }
    return rv;
}

unsigned reverse_general(unsigned val, int bits, int base) {
    /* reverse base 2**"base" digits in a "bits"-bit binary number
       bits must be <= sizeof(unsigned) * CHAR_BIT and a multiple of base
       base must be < sizeof(unsigned) * CHAR_BIT */
    unsigned rv = 0;
    for (int bit = 0; bit < bits; bit += base) {
        int digit = (val >> bit) & ((1 << base) - 1);  // extract a digit
        rv |= digit << (bits - base - bit);   // stick it in the result
    }
    return rv;
}

Upvotes: 0

R Sahu
R Sahu

Reputation: 206627

So I want to convert 0xABCD to "0xABCD". Reverse this string (which I know how to do) and then convert "0xDCBA" to 0xDCBA.

It's not too hard. You can use sprintf to save it to a string and sscanf to read from the string.

#include <iostream>
#include <cstdio>
#include <cstring>

int main()
{
   char str[20];
   int i = 0xABCD;

   // Write the number to the string
   sprintf(str, "0x%X", i);
   std::cout << str << std::endl;

   // Reverse string.
   // Pretend that I did.
   strcpy(str, "0xDCBA");

   // Read the number from the string.
   sscanf(str, "0x%X", &i);

   // Make sure you get the expected output.
   std::cout << std::hex << i << std::endl;
}

Output:

0xABCD
dcba

You can remove the "0x" from the format to make it easier for you reverse the string.

   sprintf(str, "%X", i);

and

   sscanf(str, "%X", &i);

Upvotes: 4

Related Questions