#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    3
    Rep Power
    0

    Reversing hexadecimal value with bitwise


    Hello all.

    How can I reverse a 32 bit unsigned hexadecimal value like 0xBBCCAADD to DDAACCBB with the bitwise operators?

    I can't figure out how to do it. My idea was to shift the hexadecimal value and get the last 8 bit like so:

    value<<24. That gives me DD000000 but how can I attach it and get rid of these zeros without using a char or something else, but only the bitwise operators? Or is that not possible?

    Thank you.
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,172
    Rep Power
    2222
    Changing that same memory location to the reverse, or creating a second 32-bit value in a different location?

    Ie, my question is this:
    unsigned long x = 0xBBCCAADD;
    to
    x == 0xDDAACCBB ?

    or
    unsigned long x = 0xBBCCAADD;
    to
    unsigned long y == 0xDDAACCBB ?

    Either way, you'd have a byte mask (eg, 0x000000FF) that you would AND to read out a byte from the source and OR into the target -- if you're directly modifying the source itself, then you'd have to invert the mask, or declare a second inverted mask, to blank out where you'd want to OR that byte. And shifting by 8 would be in order as well.

    Or, is the problem actually doing this nybble-wise instead of byte-wise? Eg, is it
    0x12345678 --> 0x78563412 (ie, byte-wise)
    or
    0x12345678 --> 0x87654321 (ie, nybble-wise) ?

    If the latter (ie, nybble-wise), then shifting and masking would be by 4 bits instead of by 8.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    3
    Rep Power
    0
    Originally Posted by dwise1_aol
    Changing that same memory location to the reverse, or creating a second 32-bit value in a different location?

    Ie, my question is this:
    unsigned long x = 0xBBCCAADD;
    to
    x == 0xDDAACCBB ?

    or
    unsigned long x = 0xBBCCAADD;
    to
    unsigned long y == 0xDDAACCBB ?

    Either way, you'd have a byte mask (eg, 0x000000FF) that you would AND to read out a byte from the source and OR into the target -- if you're directly modifying the source itself, then you'd have to invert the mask, or declare a second inverted mask, to blank out where you'd want to OR that byte. And shifting by 8 would be in order as well.

    Or, is the problem actually doing this nybble-wise instead of byte-wise? Eg, is it
    0x12345678 --> 0x78563412 (ie, byte-wise)
    or
    0x12345678 --> 0x87654321 (ie, nybble-wise) ?

    If the latter (ie, nybble-wise), then shifting and masking would be by 4 bits instead of by 8.
    Thanks for the reply! It is indeed, bitwise, so:
    0x12345678 --> 0x78563412.

    So I declared and initialized a unsigned int 0x000000FF (the mask). So if I have 0x12345678, I'm trying to get the last 8 bits (78) with value<<24. That gives me 7800000. Can I then, use | to assign it to the mask?
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,172
    Rep Power
    2222
    Originally Posted by TheKangaroo
    Thanks for the reply! It is indeed, bitwise, so:
    0x12345678 --> 0x78563412.
    No, that is not at all bitwise, but rather it is byte-wise! If it were truly bitwise, then the byte of 0x78 would have also been transformed:
    0x78 == 0111 1000B -> 0001 1110B == 0x1E

    That is bitwise and that is not consistent with your example. A clear, precise, unambiguous, and accurate description of the problem is always of the utmost importance!

    Originally Posted by TheKangaroo
    So I declared and initialized a unsigned int 0x000000FF (the mask). So if I have 0x12345678, I'm trying to get the last 8 bits (78) with value<<24. That gives me 7800000. Can I then, use | to assign it to the mask?
    The purpose of a mask is to mark which bits in another value to select. When selecting for copying elsewhere, ANDing with 1's copies the bit pattern in the source whose position corresponds with the 1's in the bit mask. When selecting for zeroing out (eg, in insert a different bit pattern in that portion of the target value), then ANDing with zeros causes the bits in positions corresonding with the zeros to be zero'd out. At no time is the bit mask changed in any way other than by shifting the bit mask to a different position; eg, if the bitmask starts as 0x000000FF, then it's positioned over the least significant byte (LSB), so every time you shift it left by 8 you have positioned it over the next higher byte.

    To insert the byte into the target, you would need to OR it. Two important things you need to keep in mind:
    1. the corresponding bits in the target need to be set to zero.
    2. all the other bits in the value you're ORing in need to be set to zero so that they won't change the rest of the target.

    The rest is just a matter of setting up the overall procedure. For example, you start by setting the target to zero and the bit mask to line up with one particular byte of the original value; the LSB or the MSB, your choice, makes no difference. Also declare a temporary variable to hold the byte to be transfered. Then you use the mask to assign the selected byte to the temporary variable. Shift the temporary variable so that the byte lines up with where it is to go in the target and OR the temporary variable to the target. Then shift the bit mask to line up with the next byte in the source and repeat. Obviously, the amount by which you shift the temporary variable will change each time, so be sure to keep track of that.

    Please keep in mind that I'm trying to avoid just giving you the answer, since that would not help you. Not doing others' homework for them is something of an ethical imperative in these forums.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    3
    Rep Power
    0
    Thank you very much for the reply. I will have a look at it tomorrow since I don't have access to the file anymore.

    I appreciate that you don't give me the answer, that won't help me learning of course!

    Thanks for the tip! :)
  10. #6
  11. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,891
    Rep Power
    481
    [edit:oops, answer removed]
    Yes, decide if it it bytewise, nibblewise, or bitwise. There are tricks you can play using unions and exclusive or. And maybe bit fields, if this job is is smaller than bytewise.

    As I recall, unsupported by a brief internet search, an early IBM computer used three xor operations to implement a swap word instruction.

    I'm pretty sure there's a trick to reverse AABBCCDD not just per byte but to BB33DD55.
    Last edited by b49P23TIvg; March 9th, 2013 at 05:00 PM. Reason: smiles disabled
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo