1

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.

  • In hexadecimal each symbol represents 4 bits. Each byte has 8 bits, so you can start by inverting the 4 most significant bits in each byte for the 4 least significant bits, and then just reverse the byte order. Now how many bytes your variable has will depend on it's type. – Havenard Apr 30 '17 at 04:16
  • @samz_manu, do you want to reverse the hex address itself, or the content of the bits stored inside that address? if the contents, int for example has say 4 bytes, do you want to reverse bytes or bits as whole (32bit in this case)?. – Shadi Apr 30 '17 at 04:21
  • No. That's why a lot of the answers didn't apply to me. I want to literally just reverse the hex address. Not the contents. @Shadi – move_slow_break_things Apr 30 '17 at 04:28
  • 1
    I'd really like it if you would sit and think carefully for a little while before editing and clarifying the question. As it stands, it's rather ambiguous and somewhat contradictory. `0xABCD` (a short int) requires just 16 bits or 2 bytes to represent, while on the other hand, `"0xDCBA"` (a null-terminated[?] string) requires 48bits or 6 bytes to represent. I _think_ you'd like to reverse the order of the nibbles in a 16bit number - but this is not unambiguous at present. If you're asking what I think you're asking, `R Sahu`'s answer has it nailed. – enhzflep Apr 30 '17 at 04:39

2 Answers2

4

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);
R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

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;
}
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226