dp123
dp123

Reputation: 21

Swap bytes within an unsigned long (8 bytes) in C

unsigned long swap_bytes(unsigned long n) {
    unsigned char bytes[8];
    unsigned long temp;
    bytes[0] = (n >> ??) & 0xff;
    bytes[1] = (n >> ??) & 0xff; 
    // ...
}

I am really confused on how to shift an 8 byte unsigned long from ex: 0x12345678deadbeef to 0x34127856addeefbe. I started this but I am now stuck. Please help.

Upvotes: 2

Views: 1756

Answers (3)

0___________
0___________

Reputation: 67476

universal & horrible

void swapbytes(void *p, size_t size)
{
    uint8_t tmp, *ptr = p;

    for (size_t i = 0; i < (size - 1); i += 2)
    {
        tmp = *(ptr + i);
        *(ptr + i) = *(ptr + i + 1);
        *(ptr + i + 1) = tmp;
    }
}

usage:

uint64_t n;


swapbytes(&n, sizeof n);

Upvotes: 0

Yunnosch
Yunnosch

Reputation: 26703

You can mask every other byte, in both versions, using & binary AND.
Then shift both masked values, in opposite directions and combine them using | binary OR.

n =   ((n & 0xff00ff00ff00ff00ull)>>8ull)
    | ((n & 0x00ff00ff00ff00ffull)<<8ull);

In case it is 4byte (what I consider an unsigned long in contrast to the unsigned long long, but that is implementation specific), then the code is

n =   ((n & 0xff00ff00ul)>>8ul)
    | ((n & 0x00ff00fful)<<8ul);

Upvotes: 5

J...S
J...S

Reputation: 5207

You could try this

void swap(char *ptr, int i, int j)
{
    char temp=*(ptr+i);
    *(ptr+i)=*(ptr+j);
    *(ptr+j)=temp;
}
int main()
{
    //unsigned long n = 0x12345678deadbeef;
    uint64_t n = 0x12345678deadbeef;

    char *ptr=(char *)&n;

    swap(ptr, 0, 1);
    swap(ptr, 2, 3);
    swap(ptr, 4, 5);
    swap(ptr, 6, 7);
}

The address of n is cast into a char pointer and stored in ptr.

ptr+i will give the address of the ith byte of n whose value (ie, *(ptr+i)) is modified appropriately by the swap() function.

Edit: If you are not sure if your unsigned long's size is 8 bytes, you could use uint64_t from inttypes.h.

Upvotes: 0

Related Questions