当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何在C#中将IPv4地址转换为整数?》经验,为你挑选了6个好方法。

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

解决方案应该在C#中.



1> Barry Kelly..:

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

例如,我的本地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));
    }
}


从.Net 4.0开始IPAddress.Address已“过时”。
在Ubuntu Linux 10.04上的Opera 11中确认:它将int转换回熟悉的wxyz形式,并且It Works.

2> Davy Landman..:

@Barry Kelly和@Andrew Hare,实际上,我不认为乘法是最明确的方式(完全正确).

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

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

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

所以你可以使用+添加它们,或者你可以将它们组合在一起.结果是0x40E9BB63,这是1089059683.(在我看来,以十六进制查看更容易看到字节)

所以你可以把函数写成:

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



3> Saeb Amini..:

要从IPv4转换为正确的整数:

public static uint ConvertFromIpAddressToInteger(string ipAddress)
{
    var address = IPAddress.Parse(ipAddress);
    byte[] bytes = address.GetAddressBytes();

    // flip big-endian(network order) to little-endian
    if (BitConverter.IsLittleEndian)
    {
        Array.Reverse(bytes);
    }

    return BitConverter.ToUInt32(bytes, 0);
}

public static string ConvertFromIntegerToIpAddress(uint ipAddress)
{
    byte[] bytes = BitConverter.GetBytes(ipAddress);

    // flip little-endian to big-endian(network order)
    if (BitConverter.IsLittleEndian)
    {
        Array.Reverse(bytes);
    }

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

并转换回来:

ConvertFromIpAddressToInteger("255.255.255.254"); // 4294967294
ConvertFromIntegerToIpAddress(4294967294); // 255.255.255.254

说明:

IP地址按网络顺序(big-endian),而ints在Windows上是little-endian,因此要获得正确的值,必须在转换之前反转字节.

而且,即使是IPv4,int也不能保持大于127.255.255.255例如广播地址的地址(255.255.255.255),所以使用a uint.



4> Rubens Faria..:

试试这个:

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



5> Guffa..:

由于没有人发布使用BitConverter并实际检查字节序的代码,这里有:

byte[] ip = address.Split('.').Select(s => Byte.Parse(s)).ToArray();
if (BitConverter.IsLittleEndian) {
  Array.Reverse(ip);
}
int num = BitConverter.ToInt32(ip, 0);

然后回来:

byte[] ip = BitConverter.GetBytes(num);
if (BitConverter.IsLittleEndian) {
  Array.Reverse(ip);
}
string address = String.Join(".", ip.Select(n => n.ToString()));


你需要使用uint,但这是最正确的答案.

6> Qiong Wu..:

当面对具有非常大值的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;
}

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有