33

I have this function in C# to convert a little endian byte array to an integer number:

int LE2INT(byte[] data)
{
  return (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0];
}

Now I want to convert it back to little endian.. Something like

byte[] INT2LE(int data)
{
  // ...
}

Any idea?

Thanks.

Josh
  • 68,005
  • 14
  • 144
  • 156
Yana D. Nugraha
  • 5,069
  • 10
  • 45
  • 59

9 Answers9

33

The BitConverter class can be used for this, and of course, it can also be used on both little and big endian systems.

Of course, you'll have to keep track of the endianness of your data. For communications for instance, this would be defined in your protocol.

You can then use the BitConverter class to convert a data type into a byte array and vice versa, and then use the IsLittleEndian flag to see if you need to convert it on your system or not.

The IsLittleEndian flag will tell you the endianness of the system, so you can use it as follows:

This is from the MSDN page on the BitConverter class.

  int value = 12345678; //your value
  //Your value in bytes... in your system's endianness (let's say: little endian)
  byte[] bytes = BitConverter.GetBytes(value);
  //Then, if we need big endian for our protocol for instance,
  //Just check if you need to convert it or not:
  if (BitConverter.IsLittleEndian)
     Array.Reverse(bytes); //reverse it so we get big endian.

You can find the full article here.

Hope this helps anyone coming here :)

Wracky
  • 581
  • 6
  • 5
26

Just reverse it, Note that this this code (like the other) works only on a little Endian machine. (edit - that was wrong, since this code returns LE by definition)

  byte[] INT2LE(int data)
  {
     byte[] b = new byte[4];
     b[0] = (byte)data;
     b[1] = (byte)(((uint)data >> 8) & 0xFF);
     b[2] = (byte)(((uint)data >> 16) & 0xFF);
     b[3] = (byte)(((uint)data >> 24) & 0xFF);
     return b;
  }
John Knoeller
  • 33,512
  • 4
  • 61
  • 92
  • 6
    Why would your example work only on a little-endian machine? AFAIK the bit shift method should be endian-agnostic. – nonoitall Feb 28 '10 at 05:02
  • @John, I'm pretty sure you're code works fine whether the code runs on a big- or little-endian architecture. In either case, b[0] is the lowest order byte, b[1] is the next-lowest order byte, and so on. – Dale Hagglund Feb 28 '10 at 05:03
  • My mistake, since this code returns LE rather than the natural byte order of the underlying cpu, it will work on all architectures. I'll remove the incorrect text. – John Knoeller Feb 28 '10 at 06:40
  • 2
    According to the ECMA-335 standard the conversion from uint to byte (instruction conv.i1) means simply zeroing the most signficant bytes. Therefore, the "& 0xFF" part is excessively. – SLenik Nov 24 '12 at 20:28
8

Just do it in reverse:

result[3]= (data >> 24) & 0xff;
result[2]= (data >> 16) & 0xff;
result[1]= (data >> 8)  & 0xff;
result[0]=  data        & 0xff; 
MSN
  • 53,214
  • 7
  • 75
  • 105
3

Could you use the BitConverter class? It will only work on little-endian hardware I believe, but it should handle most of the heavy lifting for you.

The following is a contrived example that illustrates the use of the class:

if (BitConverter.IsLittleEndian)
{
    int someInteger = 100;
    byte[] bytes = BitConverter.GetBytes(someInteger);
    int convertedFromBytes = BitConverter.ToInt32(bytes, 0);
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
Eric
  • 3,284
  • 1
  • 28
  • 29
2
BitConverter.GetBytes(1000).Reverse<byte>().ToArray();
1

Depending on what you're actually doing, you could rely on letting the framework handle the details of endianness for you by using IPAddress.HostToNetworkOrder and the corresponding reverse function. Then just use the BitConverter class to go to and from byte arrays.

MikeP
  • 7,829
  • 33
  • 34
1

Try using BinaryPrimitives in System.Buffers.Binary, it has helper methods for reading and writing all .net primitives in both little and big endian form.

byte[] IntToLittleEndian(int data)
{
  var output = new byte[sizeof(int)];
  BinaryPrimitives.WriteInt32LittleEndian(output, data);
  return output;
}
int LittleEndianToInt(byte[] data)
{
  return BinaryPrimitives.ReadInt32LittleEndian(data);
}
DaemonFire
  • 573
  • 6
  • 13
0
 public static string decimalToHexLittleEndian(int _iValue, int _iBytes)
    {
        string sBigEndian = String.Format("{0:x" + (2 * _iBytes).ToString() + "}", _iValue);
        string sLittleEndian = "";

        for (int i = _iBytes - 1; i >= 0; i--)
        {
            sLittleEndian += sBigEndian.Substring(i * 2, 2);
        }

        return sLittleEndian;
    }
Shawn Chin
  • 84,080
  • 19
  • 162
  • 191
0

You can use this if you don't want to use new heap allocations:

public static void Int32ToFourBytes(Int32 number, out byte b0, out byte b1, out byte b2, out byte b3)
{
    b3 = (byte)number;
    b2 = (byte)(((uint)number >> 8) & 0xFF);
    b1 = (byte)(((uint)number >> 16) & 0xFF);
    b0 = (byte)(((uint)number >> 24) & 0xFF);
}
Mendi Barel
  • 3,350
  • 1
  • 23
  • 24