Swapping 2 Bytes of Integer

the_pwner224 picture the_pwner224 · Jan 26, 2014 · Viewed 14.4k times · Source

I have a method that receives 3 parameters: int x, int n, and int m. It returns an int with the nth and mth bytes of x swapped

x is just a normal integer, set to any value. n and m are integers between 0 and 3.

For example, let the hex representation of x be 0x12345678, n is 0, and m is 2. The last and 3rd to last byte are supposed to be switched (n = 78, m = 34).

I have figured out how extract the nth and mth byte from x, but I can't figure out how to recombine all 4 bytes into the integer that the method is supposed to return.

Here is my current code: `

int byteSwap(int x, int n, int m)
{
    // Initialize variables which will hold nth and mth byte
    int xn = x;
    int xm = x;
    // If n is in bytes, n << 3 will be the number of bits in that byte
    // For example, if n is 2 (as in 2 bytes), n << 3 will be 16 (as in 16 bits)
    xn = x >> (n << 3);
    // Mask off everything except the part we want
    xn = xn & 0xFF;
    // Do the same for m
    xm = x >> (m << 3);
    xm = xm & 0xFF;
}

`

There are some additional constraints - only the following are allowed:

~ & ^ | ! + << >>

(That means no - * /, loops, ifs, etc. However, additional variables can be initialized and adding is still OK.)

My code can get the nth and mth byte extracted, but I don't get how to recombine everything without using ifs.

Answer

waTeim picture waTeim · Jan 26, 2014

Couple of things

You can recombine by masking x with a value that is all FF except for bytes m and n You can compute the mask by left shifting 0xFF m times and n times and combining the result and then XOR it with 0xFFFFFFFF

int mask = 0;
int mask_m = 0xFF << (m << 3);
int mask_n = 0xFF << (n << 3);

mask = (mask_m | mask_n) ^ 0xFFFFFFFF;

int x_swapped = (x & mask) | (xm << (n <<3)) | (xn << (m <<3));
return x_swapped;

FYI when you right shift a signed value, it may or may not propagates 1s instead of 0 into the high order bit and is implementation defined. Either way 0xFF will protect against that.