如何在 C# 中将 IPv4 地址转换为整数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/461742/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 04:18:40  来源:igfitidea点击:

How to convert an IPv4 address into a integer in C#?

c#integeripipv4

提问by GateKiller

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.

我正在寻找将标准 IPv4 地址转换为整数的函数。奖励积分可用于相反的功能。

Solution should be in C#.

解决方案应该在 C# 中。

回答by Barry Kelly

32-bit unsigned integers areIPv4 addresses. Meanwhile, the IPAddress.Addressproperty, 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).

32 位无符号整数IPv4 地址。同时,该IPAddress.Address属性虽然已被弃用,但它是一个 Int64,它返回 IPv4 地址的无符号 32 位值(问题是,它是网络字节顺序,因此您需要交换它)。

For example, my local google.com is at 64.233.187.99. That's equivalent to:

例如,我本地的 google.com 位于64.233.187.99。这相当于:

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).

而且确实, http://1089059683/按预期工作(至少在 Windows 中,使用 IE、Firefox 和 Chrome 进行了测试;但不适用于 iPhone)。

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

回答by Andrew Hare

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 firstthrough fourthbeing the segments of the IPv4 address.

first通过fourth为IPv4地址的区段。

回答by Davy Landman

@Barry Kelly and @Andrew Hare, actually, I don't think multiplying is the most clear way to do this (alltough correct).

@Barry Kelly 和@Andrew Hare,实际上,我不认为乘法是最清楚的方法(尽管正确)。

An Int32 "formatted" IP address can be seen as the following structure

一个 Int32“格式化”的 IP 地址可以看成如下结构

[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:

所以要转换 ip 地址 64.233.187.99 你可以这样做:

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

所以你可以使用 + 将它们加起来,或者你可以二进制或它们一起。结果是 0x40E9BB63,即 1089059683。(在我看来,在十六进制中查看字节更容易)

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

回答by abelenky

Take a look at some of the crazy parsing examples in .Net's IPAddress.Parse: (MSDN)

看看 .Net 的 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

"65536" ==> 0.0.255.255
"20.2" ==> 20.0.0.2
"20.65535" ==> 20.0.255.255
"128.1.2" ==> 128.1.0.2

回答by Coolcoder

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..

这为我提供了正确的 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;
    }
}

回答by Coolcoder

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.

我正在使用 LINQ、lambda 和泛型的一些扩展,因此虽然它产生相同的结果,但它使用了一些新的语言功能,您可以在三行代码中完成。

i have the explanation on my blog if you're interested.

如果你有兴趣,我在我的博客上有解释。

cheers, -jc

干杯,-jc

回答by Rubens Farias

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

回答by Rubens Farias

I think this is wrong: "65536" ==> 0.0.255.255" Should be: "65535" ==> 0.0.255.255" or "65536" ==> 0.1.0.0"

我认为这是错误的: "65536" ==> 0.0.255.255" 应该是: "65535" ==> 0.0.255.255" 或 "65536" ==> 0.1.0.0"

回答by Qiong Wu

I have encountered some problems with the described solutions, when facing IP Adresses with a very large value. The result would be, that the byte[0] * 16777216 thingy would overflow and become a negative int value. what fixed it for me, is the a simple type casting operation.

当面对具有非常大值的 IP 地址时,我遇到了所描述的解决方案的一些问题。结果是,byte[0] * 16777216 thingy 会溢出并变成负的 int 值。对我来说修复它的是一个简单的类型转换操作。

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

回答by Massimo

@Davy Ladman your solution with shift are corrent but only for ip starting with number less or equal 99, infact first octect must be cast up to long.

@Davy Ladman 您的 shift 解决方案是正确的,但仅适用于以小于或等于 99 的数字开头的 ip,实际上必须将第一个八位字节转换为 long。

Anyway convert back with long type is quite difficult because store 64 bit (not 32 for Ip) and fill 4 bytes with zeroes

无论如何转换回 long 类型是相当困难的,因为存储 64 位(不是 32 位的 Ip)并用零填充 4 个字节

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

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

Enjoy!

享受!

Massimo

马西莫