如何将IP地址增加指定的数量

本文关键字:增加 IP 地址 | 更新日期: 2023-09-27 18:00:44

我正试图弄清楚如何增加起始ip地址,并将其增加我指定的偏移量。我曾试图这样做,但我做错了,因为我得到的IP遍布各地,甚至不在同一网络范围内。

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

我正在将总ip增加一个偏移量,这样我就知道要增加多少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);
        }
    }

如何将IP地址增加指定的数量

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

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

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

等等。。

然后你可以像这样把它们"或"或"加"在一起:

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

并根据需要用CCD_ 2递增该整数。这里有一个例子:

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

以下是我用于处理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);
}

在您的周期中,您正在进行一些疯狂的增量。第一个增量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();
} 

Ip可以分解为以下

整数值=(第4个八分位数*2^24.3rd*2^16.2d*2^8.1st*2^0)

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

要进行一点评估:只需将值的数字表示从一个基数更改为另一个,在本例中,另一个是代码、头脑和计算机语言常用的10基数。以10为基数,你可以很容易地进行算术运算。完成后,将生成的数字再次更改回另一个基数,例如原始基数。

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

  • 位为2基(工具集:0,1)
  • 您的计算以10为基数(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地址是256个基数(0,1,2,3,4,5,6,7,8,9,[这里应该有另外246个唯一符号])中的(4个。由于我们没有256个唯一的数字符号(无论如何都太多了),为了方便起见,我们使用10进制来描述这些符号,例如253(但253应该是符号表中的第254个符号,就像ASCII表中一样)

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

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

他们的答案是正确的。。。用于添加到您的实施

再次检查:

如果My.Computer.Network.Ping(CheckIPFirst)=False,则

'===========如果IP地址未被占用,则获取===========

CheckIPFirst+=1

GETIpAddress(计数器)=CheckIPFirst

其他

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

CheckIPFirst+=1

转到再次检查

如果结束

这样您就不会遇到IP地址冲突或相同的IP地址。