Converting Little Endian to Big Endian
Asked Answered
E

7

22

All,

I have been practicing coding problems online. Currently I am working on a problem statement Problems where we need to convert Big Endian <-> little endian. But I am not able to jot down the steps considering the example given as:

123456789 converts to 365779719

The logic I am considering is :
1 > Get the integer value (Since I am on Windows x86, the input is Little endian)
2 > Generate the hex representation of the same.
3 > Reverse the representation and generate the big endian integer value

But I am obviously missing something here.

Can anyone please guide me. I am coding in Java 1.5

Enaenable answered 1/10, 2010 at 20:26 Comment(0)
R
22

The thing you need to realize is that endian swaps deal with the bytes that represent the integer. So the 4 byte number 27 looks like 0x0000001B. To convert that number, it needs to go to 0x1B000000... With your example, the hex representation of 123456789 is 0x075BCD15 which needs to go to 0x15CD5B07 or in decimal form 365779719.

The function Stacker posted is moving those bytes around by bit shifting them; more specifically, the statement i&0xff takes the lowest byte from i, the << 24 then moves it up 24 bits, so from positions 1-8 to 25-32. So on through each part of the expression.

For example code, take a look at this utility.

Re answered 1/10, 2010 at 20:45 Comment(1)
That's more like a 4 byte number 27... 8 byte would be: 0x000000000000001BReiner
B
40

Since a great part of writing software is about reusing existing solutions, the first thing should always be a look into the documentation for your language/library.

reverse = Integer.reverseBytes(x);

I don't know how efficient this function is, but for toggling lots of numbers, a ByteBuffer should offer decent performance.

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

...

int[] myArray = aFountOfIntegers();
ByteBuffer buffer = ByteBuffer.allocate(myArray.length*Integer.BYTES);

buffer.order(ByteOrder.LITTLE_ENDIAN);
for (int x:myArray) buffer.putInt(x);

buffer.order(ByteOrder.BIG_ENDIAN);
buffer.rewind();
int i=0;
for (int x:myArray) myArray[i++] = buffer.getInt(x);

As eversor pointed out in the comments, ByteBuffer.putInt() is an optional method, and may not be available on all Java implementations.

The DIY Approach

Stacker's answer is pretty neat, but it is possible to improve upon it.

   reversed = (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;

We can get rid of the parentheses by adapting the bitmasks. E. g., (a & 0xFF)<<8 is equivalent to a<<8 & 0xFF00. The rightmost parentheses were not necessary anyway.

   reversed = i<<24 & 0xff000000 | i<<8 & 0xff0000 | i>>8 & 0xff00 | i>>24 & 0xff;

Since the left shift shifts in zero bits, the first mask is redundant. We can get rid of the rightmost mask by using the logical shift operator, which shifts in only zero bits.

   reversed = i<<24 | i>>8 & 0xff00 | i<<8 & 0xff0000 | i>>>24;

Operator precedence here, the gritty details on shift operators are in the Java Language Specification

Burglary answered 22/4, 2015 at 9:18 Comment(4)
NOTICE that ByteBuffer.putInt() is an optional method. You might run into trouble is some systems.Larianna
The definition of the library function reverseBytes is very similar: return ((i >>> 24) ) | ((i >> 8) & 0xFF00) | ((i << 8) & 0xFF0000) | ((i << 24));Chema
Great minds think alike. ;) All the more reason to use the library function, in case a compiler knows an even better way of implementing it. Specialized hardware might be available on some architecture, for example.Burglary
I would upvote this a thousand times if I could... WAYYY too many people on the internet are trying to reinvent the wheel and I spent way too much time looking at bogus answers that do things much more complicated than necessary.Abundant
M
26

Check this out

int little2big(int i) {
    return (i&0xff)<<24 | (i&0xff00)<<8 | (i&0xff0000)>>8 | (i>>24)&0xff;
}
Muriel answered 1/10, 2010 at 20:34 Comment(4)
Perhaps clearer: return((i<<24)+((i<<8)&0x00FF0000))+((i>>8)&0x0000FF00))+(i>>>24))Centum
Also, this will switch little to big and big to little, so the method name is not broad enough. Perhaps swapEndian?Centum
Also, I would use | instead of +, on the assumption that the use of bitwise or's is likely to be faster, and easier for the compiler/runtime to optimize.Centum
I called it "int swapInt(int)"Attainder
R
22

The thing you need to realize is that endian swaps deal with the bytes that represent the integer. So the 4 byte number 27 looks like 0x0000001B. To convert that number, it needs to go to 0x1B000000... With your example, the hex representation of 123456789 is 0x075BCD15 which needs to go to 0x15CD5B07 or in decimal form 365779719.

The function Stacker posted is moving those bytes around by bit shifting them; more specifically, the statement i&0xff takes the lowest byte from i, the << 24 then moves it up 24 bits, so from positions 1-8 to 25-32. So on through each part of the expression.

For example code, take a look at this utility.

Re answered 1/10, 2010 at 20:45 Comment(1)
That's more like a 4 byte number 27... 8 byte would be: 0x000000000000001BReiner
A
17

Java primitive wrapper classes support byte reversing since 1.5 using reverseBytes method.

Short.reverseBytes(short i)
Integer.reverseBytes(int i)
Long.reverseBytes(long i)

Just a contribution for those who are looking for this answer in 2018.

Ancy answered 12/7, 2018 at 9:56 Comment(0)
F
2

I think this can also help:

int littleToBig(int i)
{
    int b0,b1,b2,b3;

    b0 = (i&0x000000ff)>>0;
    b1 = (i&0x0000ff00)>>8;
    b2 = (i&0x00ff0000)>>16;
    b3 = (i&0xff000000)>>24;

    return ((b0<<24)|(b1<<16)|(b2<<8)|(b3<<0));
}
Fasano answered 16/3, 2011 at 23:31 Comment(1)
Caution: this is not correct! The 4th assignment should be b3 = (i & 0xff000000) >>> 24 to fix it. Otherwise, if the most significant bit of i is 1 it will be copied into the most significant 24 bits of the returned result.Linnea
B
0

Just use the static function (reverseBytes(int i)) in java which is under Integer Wrapper class

Integer i=Integer.reverseBytes(123456789);
System.out.println(i);

output:

365779719
Bratcher answered 26/1, 2021 at 8:35 Comment(0)
B
-1

the following method reverses the order of bits in a byte value:

public static byte reverseBitOrder(byte b) {
    int converted = 0x00;
    converted ^= (b & 0b1000_0000) >> 7;
    converted ^= (b & 0b0100_0000) >> 5;
    converted ^= (b & 0b0010_0000) >> 3;
    converted ^= (b & 0b0001_0000) >> 1;
    converted ^= (b & 0b0000_1000) << 1;
    converted ^= (b & 0b0000_0100) << 3;
    converted ^= (b & 0b0000_0010) << 5;
    converted ^= (b & 0b0000_0001) << 7;

    return (byte) (converted & 0xFF);
}
Blowtorch answered 31/10, 2013 at 9:23 Comment(1)
Bytes themselves are not endian except in nibble based machines/software, like the old IBM mainframes from an eternity ago. In that case one swaps the lower and upper 4-bits as if they were a hi-word and a lo-word.Anonymous

© 2022 - 2024 — McMap. All rights reserved.