简体   繁体   English

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

[英]How can I increment an IP address by a specified amount?

I am trying to figure out how to increment a starting ip address, and increment it by an offset that I specify. 我试图找出如何增加一个起始IP地址,并将其增加一个我指定的偏移量。 I have attempted to do this, but I am doing something wrong because I am getting IPs that are all over the place, not even in the same network range. 我试图这样做,但我做错了,因为我得到的是各地的IP,甚至不是在同一网络范围内。

What I am currently doing is taking my starting ip and ending ip, getting the total amount of addresses then incrementing the total ips by an offset then attempting to actually increment the IP. 我目前正在做的是接受我的起始ip和结束ip,获取地址总数,然后将总ips递增一个偏移量,然后尝试实际增加IP。

I am incrementing to the total ips by an offset so I know how many to increment the ip. 我通过偏移量递增到总ips,所以我知道增加ip的数量。 (I am completing different tasks per offset.) Whatever the loop has incremented "t" to that is how many I increment IPs. (我每个偏移完成不同的任务。)无论循环增加了多少“t”,我增加了多少IP。 Now that I have given the rundown, my issue only seems to be with actually incrementing ips, can anyone help me out in this situation. 现在我已经给出了破败,我的问题似乎只是实际上增加了ips,任何人都可以在这种情况下帮助我。 Thanks. 谢谢。

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

Here is the extension class I am using. 这是我正在使用的扩展类。 They work fine. 他们工作正常。

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

An IPv4 address is basically a 32 bit Integer. IPv4地址基本上是32位整数。 Therefore you can just parse the substrings from eg 192.168.0.1 and convert each byte to an integer number: 因此,您只需解析来自例如192.168.0.1的子字符串并将每个字节转换为整数:

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

and so on .. 等等 ..

Then you could just "OR" or "ADD" them together like this: 然后你可以像这样“OR”或“添加”它们:

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

and increment that integer with step_size as needed. 并根据需要使用step_size递增该整数。 Here is an example: 这是一个例子:

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

Output 产量

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

The following is a class I use for working with IP addresses which includes the ability to increment an IP address as well as to build a range of IPs. 以下是我用于处理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();
    }
}

You could also implement the + and - operators for the IPAddress class, but since it wouldn't work for all uses of the class it's probably not a good idea. 您也可以为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);
}

In your cycle you are doing some wild increments. 在你的周期中,你正在做一些疯狂的增量。 First increment t is 0 so ip stays the same. 第一个增量t0所以ip保持不变。 Second increment t is 3 so 192.168.1.1 becomes 192.168.1.4 (and you save it as current). 第二个增量t3因此192.168.1.1变为192.168.1.4 (并将其保存为当前值)。 Third increment t is 6 so 192.168.1.4 becomes 192.168.1.10 (and saved as current) ... 第三个增量t6因此192.168.1.4变为192.168.1.10 (并保存为当前值)...

I think what you are trying to achieve is somthing like this: 我认为你想要实现的是这样的事情:

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

Ip can be decomposed as follow Ip可以分解如下

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

eg 64.233.187.99 例如64.233.187.99

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

I wrote this small example for you, 我为你写了这个小例子,

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

To evaluate a little: You simply change the numeric representation of a value from one base to another, the another in this case being the 10-base, which your code, your head and your computer language use commonly. 稍微评估:您只需将值的数字表示从一个基础更改为另一个基础 ,另一个在这种情况下是10个基础,您的代码,头部和计算机语言通常使用。 In 10-base, you can easily perform arithmetics. 在10-base中,您可以轻松执行算术。 Once you have done that, you change the resulting number back to another base again, for example the original one. 完成后,再次将结果数字更改回另一个基数,例如原始数字。

In the case of an IP-address, the base is 256. As said earlier, an IP-address is simply a numeric value consisting 32 bits. 在IP地址的情况下,基数是256.如前所述,IP地址只是一个由32位组成的数值。

  • Bits are 2-base (toolset: 0,1) 比特是2基(工具集:0,1)
  • Your calculation happens in 10-base (0,1,2,3,4,5,6,7,8,9) 你的计算是在10基(0,1,2,3,4,5,6,7,8,9)
  • Hexa is 16-base ((0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F) Hexa是16碱基((0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F)
  • An IP-address is (4 of) 256-base (0,1,2,3,4,5,6,7,8,9,[we should have another 246 unique symbols here]). IP地址是(4)256基(0,1,2,3,4,5,6,7,8,9,[我们这里应该有另外246个唯一符号])。 As we do not have 256 unique numeric symbols (would be too many anyway), we describe these for convenience using 10-base instead, for example 253 (but 253 should really be the 254th symbol in a symbol table, like in the ASCII-table). 由于我们没有256个唯一的数字符号(无论如何都会有太多),我们为了方便而使用10-base来描述这些,例如253(但253应该是符号表中的第254个符号,就像在ASCII-中一样)表)。

There are a million cases when you want to change base, or change numeric space. 当您想要更改基础或更改数字空间时,有一百万种情况。 One example is incrementing a date. 一个例子是递增日期。 You change to the manageable days-since-20th-centurystart-space (the actual change isn't too simple, but the good result is a 10-base representation), perform the calculation (eg. increment with 7 days), and then change back to YMD-space. 你改为20世纪以来的可管理天数(实际变化不是太简单,但好的结果是10基表示),执行计算(例如7天增量),然后改回YMD空间。

The IP-address 255.255.255.255 could also be described using the 10-base integer value 4294967295. 也可以使用10基整数值4294967295来描述IP地址255.255.255.255。

They Answers are right... for addition to your implementation 他们的答案是正确的......除了您的实施

CheckAgain: 再检查一遍:

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

'=====IF IP ADDRESS NOT OCCUPIED GET========= '=====如果IP地址未被占用,请加入=========

CheckIPFirst +=1 CheckIPFirst + = 1

GETIpAddress(Counter) = CheckIPFirst GETIpAddress(Counter)= CheckIPFirst

Else 其他

'======CHECK ANOTHER IP ADDRESS============= '======检查另一个IP地址=============

CheckIPFirst +=1 CheckIPFirst + = 1

Goto CheckAgain 转到CheckAgain

End If 万一

Through that you will not encounter a IP Address Conflict or Same IP Address. 通过这种方式,您将不会遇到IP地址冲突或相同的IP地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM