Как преобразовать адрес IPv4 в целое число в C#?

96
задан Eric Leschinski 19 July 2013 в 03:46
поделиться

8 ответов

32-разрядные целые числа без знака адреса IPv4. Между тем IPAddress.Address свойство, в то время как удерживается от использования, является Int64, который возвращает неподписанное 32-разрядное значение адреса IPv4 (выгода, это находится в сетевом порядке байтов, таким образом, необходимо подкачать его вокруг).

, Например, мой локальный google.com в 64.233.187.99. Это эквивалентно:

64*2^24 + 233*2^16 + 187*2^8 + 99
= 1089059683

И действительно, http://1089059683/ работы как ожидалось (по крайней мере, в Windows, протестированном с IE, Firefox и Chrome; не работает над iPhone хотя).

Вот тестовая программа для показа обоих преобразований, включая свопинг байта сети/хоста:

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));
    }
}
137
ответ дан Barry Kelly 24 November 2019 в 05:33
поделиться

Смотрите на некоторые сумасшедшие примеры парсинга в IPAddress.Net. Синтаксический анализ: ( 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

-1
ответ дан abelenky 24 November 2019 в 05:33
поделиться

Если Вы интересовались функцией не только, ответ здесь - то, как это сделано:

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

с first до fourth являющийся сегментами адреса IPv4.

1
ответ дан Andrew Hare 24 November 2019 в 05:33
поделиться

Мой вопрос был закрыт, я понятия не имею почему. Принятый ответ здесь не является тем же как, в чем я нуждаюсь.

Это дает мне корректное целочисленное значение для 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;
    }
}
3
ответ дан Noctis 24 November 2019 в 05:33
поделиться

@Barry Kelly и @Andrew Hare, на самом деле, я не думаю, умножаясь, самый ясный способ сделать это (alltough корректный).

"отформатированный" IP-адрес Int32 может рассматриваться как следующая структура

[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

Так для преобразования IP-адреса 64.233.187.99, Вы могли сделать:

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

, таким образом, Вы могли добавить их использующий + или Вы могли binairy или они вместе. Приведение к 0x40E9BB63, который является 1089059683. (По-моему, смотрящий в шестнадцатеричном числе намного легче видеть байты)

, Таким образом, Вы могли записать функцию как:

int ipToInt(int first, int second, 
    int third, int fourth)
{
    return (first << 24) | (second << 16) | (third << 8) | (fourth);
}
39
ответ дан Davy Landman 24 November 2019 в 05:33
поделиться

вот решение, которое я разработал сегодня (следовало бы сначала погуглить!):

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

Я использую LINQ, лямбду и некоторые расширения для дженериков, поэтому пока он производит тот же результат, он использует некоторые новые языковые функции, и вы можете сделать это в трех строках кода.

У меня есть объяснение в моем блоге, если вам интересно.

ура, -jc

0
ответ дан 24 November 2019 в 05:33
поделиться

Попробуйте следующие:

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();
}
12
ответ дан 24 November 2019 в 05:33
поделиться

Я считаю, что это неправильно: "65536" ==> 0.0.255.255 " Должно быть: "65535" ==> 0.0.255.255 "или" 65536 "==> 0.1.0.0"

0
ответ дан 24 November 2019 в 05:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: