[c#] ¿Cómo convertir una dirección IPv4 en un número entero en C #?


Answers

@Barry Kelly y @Andrew Hare, en realidad, no creo que la multiplicación sea la forma más clara de hacer esto (todo correcto).

Una dirección IP "formateada" Int32 se puede ver como la siguiente estructura

[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

Entonces para convertir la dirección IP 64.233.187.99 podrías hacer:

(64  = 0x40) << 24 == 0x40000000
(233 = 0xE9) << 16 == 0x00E90000
(187 = 0xBB) << 8  == 0x0000BB00
(99  = 0x63)       == 0x00000063
                      ---------- =|
                      0x40E9BB63

para que pueda sumarlos usando + o puede binairy o juntos. Resultando en 0x40E9BB63 que es 1089059683. (En mi opinión, mirando en hexadecimal es mucho más fácil ver los bytes)

Entonces podrías escribir la función como:

int ipToInt(int first, int second, 
    int third, int fourth)
{
    return (first << 24) | (second << 16) | (third << 8) | (fourth);
}
Question

Estoy buscando una función que convierta una dirección IPv4 estándar en un Entero. Puntos de bonificación disponibles para una función que hará lo contrario.

La solución debe estar en C #.




    public static Int32 getLongIPAddress(string ipAddress)
    {
        return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(IPAddress.Parse(ipAddress).GetAddressBytes(), 0));
    }

El ejemplo anterior sería la forma en que voy. Lo único que tendrías que hacer es convertir a un UInt32 para fines de visualización o con fines de cadena, incluido su uso como una dirección larga en forma de cadena.

Que es lo que se necesita cuando se usa la función IPAddress.Parse (String). Suspiro.




He encontrado algunos problemas con las soluciones descritas, al enfrentar Direcciones IP con un valor muy grande. El resultado sería que el byte [0] * 16777216 se desbordará y se convertirá en un valor int negativo. Lo que lo solucionó fue una operación de conversión de tipo simple.

public static long ConvertIPToLong(string ipAddress)
{
    System.Net.IPAddress ip;

    if (System.Net.IPAddress.TryParse(ipAddress, out ip))
    {
        byte[] bytes = ip.GetAddressBytes();

        return (long)
            (
            16777216 * (long)bytes[0] +
            65536 * (long)bytes[1] +
            256 * (long)bytes[2] +
            (long)bytes[3]
            )
            ;
    }
    else
        return 0;
}



var ipAddress = "10.101.5.56";

var longAddress = long.Parse(string.Join("", ipAddress.Split('.').Select(x => x.PadLeft(3, '0'))));

Console.WriteLine(longAddress);

Salida: 10101005056




Con UInt32 en el formato apropiado little-endian, aquí hay dos funciones simples de conversión:

public uint GetIpAsUInt32(string ipString)
{
    IPAddress address = IPAddress.Parse(ipString);

    byte[] ipBytes = address.GetAddressBytes();

    Array.Reverse(ipBytes);

    return BitConverter.ToUInt32(ipBytes, 0);
}

public string GetIpAsString(uint ipVal)
{
    byte[] ipBytes = BitConverter.GetBytes(ipVal);

    Array.Reverse(ipBytes);

    return new IPAddress(ipBytes).ToString();
}



El reverso de la función de Davy Landman

string IntToIp(int d)
{
  int v1 = d & 0xff;
  int v2 = (d >> 8) & 0xff;
  int v3 = (d >> 16) & 0xff;
  int v4 = (d >> 24);
  return v4 + "." + v3 + "." + v2 + "." + v1;
}



he aquí una solución que resolví hoy (¡debería haber buscado primero en Google!):

    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();
    }

Estoy usando LINQ, lambda y algunas de las extensiones en genéricos, por lo que, aunque produce el mismo resultado, utiliza algunas de las nuevas características del lenguaje y puede hacerlo en tres líneas de código.

tengo la explicación en mi blog si estás interesado.

vivas, -jc




@Davy Ladman su solución con shift es corrent pero solo para ip comenzando con un número menor o igual a 99, de hecho el primer octeto debe ser lanzado a largo.

De todos modos, la conversión de vuelta con tipo largo es bastante difícil porque almacena 64 bit (no 32 para Ip) y llena 4 bytes con ceros

static uint ToInt(string addr)
{
   return BitConverter.ToUInt32(IPAddress.Parse(addr).GetAddressBytes(), 0);
}

static string ToAddr(uint address)
{
    return new IPAddress(address).ToString();
}

¡Disfrutar!

Massimo




Prueba esto:

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();
}



Eche un vistazo a algunos de los ejemplos de análisis loco en .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




Links