I'm looking for a function that will convert a standard IPv4 address into an Integer. Bonus points available for a function that will do the opposite.
Solution should be in C#.
I'm looking for a function that will convert a standard IPv4 address into an Integer. Bonus points available for a function that will do the opposite.
Solution should be in C#.
32-bit unsigned integers are IPv4 addresses. Meanwhile, the IPAddress.Address property, while deprecated, is an Int64 that returns the unsigned 32-bit value of the IPv4 address (the catch is, it's in network byte order, so you need to swap it around).
For example, my local google.com is at 64.233.187.99. That's equivalent to:
64*2^24 + 233*2^16 + 187*2^8 + 99
= 1089059683
And indeed, http://1089059683/ works as expected (at least in Windows, tested with IE, Firefox and Chrome; doesn't work on iPhone though).
Here's a test program to show both conversions, including the network/host byte swapping:
using System;
using System.Net;
class App
{
static long ToInt(string addr)
{
// careful of sign extension: convert to uint first;
// unsigned NetworkToHostOrder ought to be provided.
return (long) (uint) IPAddress.NetworkToHostOrder(
(int) IPAddress.Parse(addr).Address);
}
static string ToAddr(long address)
{
return IPAddress.Parse(address.ToString()).ToString();
// This also works:
// return new IPAddress((uint) IPAddress.HostToNetworkOrder(
// (int) address)).ToString();
}
static void Main()
{
Console.WriteLine(ToInt("64.233.187.99"));
Console.WriteLine(ToAddr(1089059683));
}
}
@Barry Kelly and @Andrew Hare, actually, I don't think multiplying is the most clear way to do this (alltough correct).
An Int32 "formatted" IP address can be seen as the following structure
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct IPv4Address
{
public Byte A;
public Byte B;
public Byte C;
public Byte D;
}
// to actually cast it from or to an int32 I think you
// need to reverse the fields due to little endian
So to convert the ip address 64.233.187.99 you could do:
(64 = 0x40) << 24 == 0x40000000
(233 = 0xE9) << 16 == 0x00E90000
(187 = 0xBB) << 8 == 0x0000BB00
(99 = 0x63) == 0x00000063
---------- =|
0x40E9BB63
so you could add them up using + or you could binairy or them together. Resulting in 0x40E9BB63 which is 1089059683. (In my opinion looking in hex it's much easier to see the bytes)
So you could write the function as:
int ipToInt(int first, int second,
int third, int fourth)
{
return (first << 24) | (second << 16) | (third << 8) | (fourth);
}
Try this ones:
private int IpToInt32(string ipAddress)
{
return BitConverter.ToInt32(IPAddress.Parse(ipAddress).GetAddressBytes().Reverse().ToArray(), 0);
}
private string Int32ToIp(int ipAddress)
{
return new IPAddress(BitConverter.GetBytes(ipAddress).Reverse().ToArray()).ToString();
}
My question was closed, I have no idea why . The accepted answer here is not the same as what I need.
This gives me the correct integer value for an IP..
public double IPAddressToNumber(string IPaddress)
{
int i;
string [] arrDec;
double num = 0;
if (IPaddress == "")
{
return 0;
}
else
{
arrDec = IPaddress.Split('.');
for(i = arrDec.Length - 1; i >= 0 ; i = i -1)
{
num += ((int.Parse(arrDec[i])%256) * Math.Pow(256 ,(3 - i )));
}
return num;
}
}
If you were interested in the function not just the answer here is how it is done:
int ipToInt(int first, int second,
int third, int fourth)
{
return Convert.ToInt32((first * Math.Pow(256, 3))
+ (second * Math.Pow(256, 2)) + (third * 256) + fourth);
}
with first through fourth being the segments of the IPv4 address.
Multiply all the parts of the IP number by powers of 256 (256x256x256, 256x256, 256 and 1. For example:
IPv4 address : 127.0.0.1 32 bit number: = (127x256^3) + (0x256^2) + (0x256^1) + 1 = 2130706433
here's a solution that I worked out today (should've googled first!):
private static string IpToDecimal2(string ipAddress)
{
// need a shift counter
int shift = 3;
// loop through the octets and compute the decimal version
var octets = ipAddress.Split('.').Select(p => long.Parse(p));
return octets.Aggregate(0L, (total, octet) => (total + (octet << (shift-- * 8)))).ToString();
}
i'm using LINQ, lambda and some of the extensions on generics, so while it produces the same result it uses some of the new language features and you can do it in three lines of code.
i have the explanation on my blog if you're interested.
cheers, -jc
I think this is wrong: "65536" ==> 0.0.255.255" Should be: "65535" ==> 0.0.255.255" or "65536" ==> 0.1.0.0"
I use this:
public static uint IpToUInt32(string ip)
{
if (!IPAddress.TryParse(ip, out IPAddress address)) return 0;
return BitConverter.ToUInt32(address.GetAddressBytes(), 0);
}
public static string UInt32ToIp(uint address)
{
return new IPAddress(address).ToString();
}
Take a look at some of the crazy parsing examples in .Net's IPAddress.Parse: (MSDN)
"65536" ==> 0.0.255.255
"20.2" ==> 20.0.0.2
"20.65535" ==> 20.0.255.255
"128.1.2" ==> 128.1.0.2
I noticed that System.Net.IPAddress have Address property (System.Int64) and constructor, which also accept Int64 data type. So you can use this to convert IP address to/from numeric (although not Int32, but Int64) format.