Question

I try to convert an Ip Address to a long value :

byte[] Ip = new byte[4] { 192, 168, 1, 0 };

UInt32 Ret1 = (((UInt32)Ip[0]) << 24) |
              (((UInt32)Ip[1]) << 16) |
              (((UInt32)Ip[2]) << 8)  |
              (((UInt32)Ip[3]));

UInt32 Ret2 = BitConverter.ToUInt32(Ip, 0);

Ret1 returns 3232235776 (the correct value)

Ret2 returns 108736 (?)

Why this difference ?

Was it helpful?

Solution

Indeed, endianness is your issue here. While not difficult to work around, it can be annoying at times on Intel-based systems due to them being in Little Endian whereas Network Order is Big Endian. In short, your bytes are in the reverse order.

Here is a little convenience method you may use to solve this issue (and even on various platforms):

static uint MakeIPAddressInt32(byte[] array)
{
  // Make a defensive copy.
  var ipBytes = new byte[array.Length];
  array.CopyTo(ipBytes, 0);

  // Reverse if we are on a little endian architecture.
  if(BitConverter.IsLittleEndian)
    Array.Reverse(ipBytes);

  // Convert these bytes to an unsigned 32-bit integer (IPv4 address).
  return BitConverter.ToUInt32(ipBytes, 0);
} 

OTHER TIPS

Sounds like you have a problem with endianness.

http://en.wikipedia.org/wiki/Endianness

The platform (bitness) independent code can looks lake this:

UInt32 Ret2 = BitConverter.ToUInt32(
                   BitConverter.IsLittleEndian
                   ? Ip.Reverse().ToArray()
                   : Ip, 0);

It's an endian issue. IPAddress.HostToNetworkOrder has various overloads for converting numeric types to their network equivilant (ie little endian to big endian).

IP addresses are typically written in Network Byte Order which happens to be the other endianness of standard x86.

Google for aton(), ntoa() and big endian.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top