如何按指定数量增加IP地址?

时间:2014-04-29 06:08:32

标签: c# .net

我试图找出如何递增起始IP地址,并将其增加一个我指定的偏移量。我试图这样做,但我做错了,因为我得到的是各地的IP,甚至不是在同一网络范围内。

我目前正在做的是取出我的起始IP和结束ip,获取地址总数,然后将总ips递增一个偏移量,然后尝试实际增加IP。

我通过偏移递增到总ips,所以我知道增加ip的数量。 (我每个偏移完成不同的任务。)无论循环增加了什么" t"这就是我增加IP的数量。现在我已经给出了破败,我的问题似乎只是实际上增加了ips,任何人都可以在这种情况下帮助我。感谢。

            string from = txtStart.Text, to = txtEnd.Text;
            uint current = from.ToUInt(), last = to.ToUInt();

            ulong total = last - current;
            int offset = 3; //This is an example number, it actually could be anything.

            while (current <= last)
            {
             for (int t = 0; t < total; t += offset)
                    {
                        uint ut = Convert.ToUInt32(t);
                        current = current + ut;
                        var ip = current.ToIPAddress();
                    }  
              }

这是我正在使用的扩展类。他们工作正常。

public static class Extensions
    {
        public static uint ToUInt(this string ipAddress)
        {
            var ip = IPAddress.Parse(ipAddress);
            var bytes = ip.GetAddressBytes();
            Array.Reverse(bytes);
            return BitConverter.ToUInt32(bytes, 0);
        }

        public static string ToString(this uint ipInt)
        {
            return ToIPAddress(ipInt).ToString();
        }

        public static IPAddress ToIPAddress(this uint ipInt)
        {
            var bytes = BitConverter.GetBytes(ipInt);
            Array.Reverse(bytes);
            return new IPAddress(bytes);
        }
    }

7 个答案:

答案 0 :(得分:6)

[TestFixture]
public class GetNextIpAddressTest
{
    [Test]
    public void ShouldGetNextIp()
    {
        Assert.AreEqual("0.0.0.1", GetNextIpAddress("0.0.0.0", 1));
        Assert.AreEqual("0.0.1.0", GetNextIpAddress("0.0.0.255", 1));
        Assert.AreEqual("0.0.0.11", GetNextIpAddress("0.0.0.1", 10));
        Assert.AreEqual("123.14.1.101", GetNextIpAddress("123.14.1.100", 1));
        Assert.AreEqual("0.0.0.0", GetNextIpAddress("255.255.255.255", 1));
    }

    private static string GetNextIpAddress(string ipAddress, uint increment)
    {
        byte[] addressBytes = IPAddress.Parse(ipAddress).GetAddressBytes().Reverse().ToArray();
        uint ipAsUint = BitConverter.ToUInt32(addressBytes, 0);
        var nextAddress = BitConverter.GetBytes(ipAsUint + increment);
        return String.Join(".", nextAddress.Reverse());
    }
}

答案 1 :(得分:3)

IPv4地址基本上是32位整数。因此,您只需解析子串,例如: 192.168.0.1并将每个字节转换为整数:

uint byte1 = Converter.ToUint32("192");

依旧......

然后你可以像这样“或”将它们组合在一起:

uint IP = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;

并根据需要使用step_size增加该整数。这是一个例子:

using System.IO;
using System;

class Program
{
    static void Main()
    {

        String ipString = "192.168.0.1";

        String[] ipBytes = ipString.Split('.');

        uint byte1 = Convert.ToUInt32(ipBytes[0]);
        uint byte2 = Convert.ToUInt32(ipBytes[1]);
        uint byte3 = Convert.ToUInt32(ipBytes[2]);
        uint byte4 = Convert.ToUInt32(ipBytes[3]);

        uint IP =   (byte1 << 24) 
                  | (byte2 << 16) 
                  | (byte3 <<  8) 
                  |  byte4 ;

        uint step_size = 90000000;

        while( IP != 0xFFFFFFFF ) {

            Console.WriteLine(
                  ((IP >> 24) & 0xFF) + "." +
                  ((IP >> 16) & 0xFF) + "." +
                  ((IP >> 8 ) & 0xFF) + "." +
                  ( IP        & 0xFF)
                );

             // if (0xFFFFFFFF - IP) < step_size then we can't 
             // add step_size to IP due to integer overlow
             // which means that we have generated all IPs and 
             // there isn't any left that equals IP + step_size
             if( (0xFFFFFFFF - IP) < step_size ) {
                 break;
             }

             IP += step_size; // next ip address
        }
    }
}

输出

192.168.0.1
198.5.74.129
203.98.149.1
208.191.223.129
214.29.42.1
219.122.116.129
224.215.191.1
230.53.9.129
235.146.84.1
240.239.158.129
246.76.233.1
251.170.51.129

答案 2 :(得分:1)

以下是我用于处理IP地址的类,其中包括增加IP地址以及构建一系列IP的功能。

public sealed class IPAddressTools
{
    public static UInt32 ConvertIPv4AddressToUInt32(IPAddress address)
    {
        if (address == null) throw new ArgumentNullException("address", "The value of address is a null reference.");
        if (address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) throw new ArgumentException("The specified address's family is invalid.", "address");

        Byte[] addressBytes = address.GetAddressBytes();
        UInt32 addressInteger = (((UInt32)addressBytes[0]) << 24) + (((UInt32)addressBytes[1]) << 16) + (((UInt32)addressBytes[2]) << 8) + ((UInt32)addressBytes[3]);
        return addressInteger;
    }
    public static IPAddress ConvertUInt32ToIPv4Address(UInt32 addressInteger)
    {
        if (addressInteger < 0 || addressInteger > 4294967295) throw new ArgumentOutOfRangeException("addressInteger", "The value of addressInteger must be between 0 and 4294967295.");

        Byte[] addressBytes = new Byte[4];
        addressBytes[0] = (Byte)((addressInteger >> 24) & 0xFF);
        addressBytes[1] = (Byte)((addressInteger >> 16) & 0xFF);
        addressBytes[2] = (Byte)((addressInteger >> 8) & 0xFF);
        addressBytes[3] = (Byte)(addressInteger & 0xFF);
        return new IPAddress(addressBytes);
    }
    public static IPAddress IncrementIPAddress(IPAddress address, int offset)
    {
        return ModIPAddress(address, 1);
    }
    public static IPAddress ModIPAddress(IPAddress address, int offset)
    {
        if (address == null) throw new ArgumentNullException("address", "The value of address is a null reference.");
        if (address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) throw new ArgumentException("The specified address's family is invalid.");

        UInt32 addressInteger = ConvertIPv4AddressToUInt32(address);
        addressInteger += offset;
        return ConvertUInt32ToIPv4Address(addressInteger);
    }
    public static IPAddress[] GetIpRange(IPAddress address, IPAddress mask)
    {
        if (address == null) throw new ArgumentNullException("address", "The value of address is a null reference.");
        if (mask == null) throw new ArgumentNullException("mask", "The value of mask is a null reference.");
        if (address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) throw new ArgumentException("The specified address's family is invalid.");
        if (mask.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) throw new ArgumentException("The specified mask's family is invalid.");

        byte[] addressBytes = address.GetAddressBytes();
        byte[] maskBytes = mask.GetAddressBytes();
        byte[] startIpBytes = new byte[addressBytes.Length];
        byte[] endIpBytes = new byte[addressBytes.Length];

        for (int i = 0; i < addressBytes.Length; i++)
        {
            startIpBytes[i] = (byte)(addressBytes[i] & maskBytes[i]);
            endIpBytes[i] = (byte)(addressBytes[i] | ~maskBytes[i]);
        }

        IPAddress startIp = new IPAddress(startIpBytes);
        IPAddress endIp = new IPAddress(endIpBytes);

        List<IPAddress> addresses = new List<IPAddress>();

        for (IPAddress currentIp = startIp; ConvertIPv4AddressToUInt32(currentIp) <= ConvertIPv4AddressToUInt32(endIp); currentIp = IncrementIPAddress(currentIp))
        {
            addresses.Add(currentIp);
        }

        return addresses.ToArray();
    }
}

您还可以为IPAddress类实现+-运算符,但由于它不适用于该类的所有用途,因此它可能不是一个好主意

public static IPAddress operator +(IPAddress address, int offset)
{
    if (address == null) throw new ArgumentNullException("address", "The value of address is a null reference.");
    if (address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) throw new ArgumentException("The specified address's family is invalid.", "address");

    Byte[] addressBytes = address.GetAddressBytes();
    UInt32 addressInteger = (((UInt32)addressBytes[0]) << 24) + (((UInt32)addressBytes[1]) << 16) + (((UInt32)addressBytes[2]) << 8) + ((UInt32)addressBytes[3]);
    addressInteger += offset;
    addressBytes[0] = (Byte)((addressInteger >> 24) & 0xFF);
    addressBytes[1] = (Byte)((addressInteger >> 16) & 0xFF);
    addressBytes[2] = (Byte)((addressInteger >> 8) & 0xFF);
    addressBytes[3] = (Byte)(addressInteger & 0xFF);
    return new IPAddress(addressBytes);
}
public static IPAddress operator -(IPAddress address, int offset)
{
    if (address == null) throw new ArgumentNullException("address", "The value of address is a null reference.");
    if (address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork) throw new ArgumentException("The specified address's family is invalid.", "address");

    Byte[] addressBytes = address.GetAddressBytes();
    UInt32 addressInteger = (((UInt32)addressBytes[0]) << 24) + (((UInt32)addressBytes[1]) << 16) + (((UInt32)addressBytes[2]) << 8) + ((UInt32)addressBytes[3]);
    addressInteger -= offset;
    addressBytes[0] = (Byte)((addressInteger >> 24) & 0xFF);
    addressBytes[1] = (Byte)((addressInteger >> 16) & 0xFF);
    addressBytes[2] = (Byte)((addressInteger >> 8) & 0xFF);
    addressBytes[3] = (Byte)(addressInteger & 0xFF);
    return new IPAddress(addressBytes);
}

答案 3 :(得分:0)

在你的循环中,你正在做一些疯狂的增量。第一个增量t0,所以ip保持不变。第二个增量t3,因此192.168.1.1变为192.168.1.4(并将其保存为当前值)。第三个增量t6,因此192.168.1.4变为192.168.1.10(并保存为当前)......

我认为你想要实现的是这样的事情:

string from = "192.168.1.1", to = "192.168.1.255";
uint first = from.ToUInt(), last = to.ToUInt();

ulong total = last - first;
uint offset = 3; //This is an example number, it actually could be anything.

for (uint t = 0; (ulong)t < total; t += 1)
{
    uint ut = Convert.ToUInt32(t);
    uint c = first + t + offset;
    var ip = c.ToIPAddress();
} 

答案 4 :(得分:0)

Ip可以按照以下方式分解

整数值=(4thOctat * 2 ^ 24.3rd * 2 ^ 16.2nd * 2 ^ 8.1st * 2 ^ 0)

e.g。 64.233.187.99

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

我为你写了这个小例子,

    //This is regular expression to check the the ip is in correct format 
    private readonly Regex ip = new Regex(@"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$");

    private void Main()
    {
        string IpAddress = "172.22.1.1";

        if (ip.IsMatch(IpAddress))
        {                
            //increment first octat by 5
            string IncrementedIp = IncrementIP(0, 100, IPAddress.Parse(IpAddress));
            if (ip.IsMatch(IncrementedIp))
            {
                Console.WriteLine("Incremented Ip = {0}", IncrementedIp);
            }
            else
            {
                //not valid ip address}
            }
        }else
        {
            //Not Valid Ip Address
        }

    }

    private string IncrementIP(short octat, long Offset,IPAddress adress)
    {
        //octat range from 0-3
        if ( octat<0 ||octat > 3) return adress.ToString();

        long IpLong = AdressToInt(adress.ToString());
        IpLong += (long)(Offset*(Math.Pow(2,octat*8)));
        return longToAddress(IpLong);
    }
    static long AdressToInt(string addr)
    {
        return (long)(uint)IPAddress.NetworkToHostOrder(
             (int)IPAddress.Parse(addr).Address);
    }

    static string longToAddress(long address)
    {
        return IPAddress.Parse(address.ToString()).ToString();
    }

答案 5 :(得分:0)

要评估一下:您只需将值的数字表示从一个 base 更改为另一个,另一个在这种情况下是10-base,您的代码,您的头和您的计算机语言使用一般。在10-base中,您可以轻松执行算术。完成后,再次将结果数字更改回另一个基数,例如原始数字。

在IP地址的情况下,基数为256.如前所述,IP地址只是一个由32位组成的数值。

  • 比特是2基(工具集:0,1)
  • 您的计算以10-base(0,1,2,3,4,5,6,7,8,9)
  • 进行
  • Hexa是16碱基((0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F)
  • IP地址是(4)256基(0,1,2,3,4,5,6,7,8,9,[我们这里应该有另外246个唯一符号])。由于我们没有256个唯一的数字符号(无论如何都会有太多),我们为了方便而使用10-base来描述这些,例如253(但253应该是符号表中的第254个符号,就像在ASCII-中一样)表)。

当您想要更改基础或更改数字空间时,有一百万种情况。一个例子是递增日期。你改为20世纪以来的可管理天数(实际变化不是太简单,但好的结果是10基表示),执行计算(例如7天增量),然后改回YMD-space。

也可以使用10基整数值4294967295来描述IP地址255.255.255.255。

答案 6 :(得分:-1)

他们的答案是正确的...添加到您的实施

CheckAgain:

如果My.Computer.Network.Ping(CheckIPFirst)= False那么

'=====如果IP地址未被占用,请加入=========

CheckIPFirst + = 1

GETIpAddress(Counter)= CheckIPFirst

否则

'======检查另一个IP地址=============

CheckIPFirst + = 1

转到CheckAgain

结束如果

通过这种方式,您将不会遇到IP地址冲突或相同的IP地址。