以字符串格式递增IP地址

6
我是新手,正在尝试通过用户输入的IP地址范围进行增量。比如从192.168.0.1到192.168.0.255。然而,目前我的应用程序处理方式是将“开始”和“结束”IP地址作为字符串。有没有办法逐个遍历用户输入的“开始”和“结束”IP地址?希望这能理解,并请不要责备我,我已经在寻找答案!(注:此处代码略)
    public static String stringPing(String stringPing, String host){

    String ipAddress;
    ipAddress = host;

    try
    {
        InetAddress inet = InetAddress.getByName(ipAddress);

        boolean status = inet.isReachable(2000); 

        if (status)
        {
            stringPing = "\n" +host +" is reachable";
            return stringPing;
        }
        else
        {
            stringPing = "\n" +host +" is unreachable";
            return stringPing;
        }
    }
    catch (UnknownHostException e)
    {
        System.err.println("Host does not exists");
    }
    catch (IOException e)
    {
        System.err.println("Error in reaching the Host");
    }

    return stringPing;

}  

如果你想得到帮助,就需要展示一些代码。你的问题也有点令人困惑...你所说的“increment through”是指迭代吗?如果你能保证用户输入的格式正确,你可以在句号处将其分割并使用parseInt创建一个数字,然后继续进行直到达到255 - David Titarenco
用户输入起始和终止地址。我必须找到一种方法来循环遍历用户输入的范围... - Matt
请看下面 @Dims 的答案。这是正确的方法,适用于任何 IP 范围(不仅限于 C 类)。IPv4 地址只是网络字节顺序(大端)中的 4 字节整数。 - Brian Roach
非常感谢,我刚看了一些答案,Dims 看起来很适合这个目的 :) - Matt
5个回答

16

将地址保存为32位整数并按此形式递增。仅在必要时将其从或转换为String。以下是示例。我的IPAddress类已经完整并且可用。

class IPAddress {

    private final int value;

    public IPAddress(int value) {
        this.value = value;
    }

    public IPAddress(String stringValue) {
        String[] parts = stringValue.split("\\.");
        if( parts.length != 4 ) {
            throw new IllegalArgumentException();
        }
        value = 
                (Integer.parseInt(parts[0], 10) << (8*3)) & 0xFF000000 | 
                (Integer.parseInt(parts[1], 10) << (8*2)) & 0x00FF0000 |
                (Integer.parseInt(parts[2], 10) << (8*1)) & 0x0000FF00 |
                (Integer.parseInt(parts[3], 10) << (8*0)) & 0x000000FF;
    }

    public int getOctet(int i) {

        if( i<0 || i>=4 ) throw new IndexOutOfBoundsException();

        return (value >> (i*8)) & 0x000000FF;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();

        for(int i=3; i>=0; --i) {
            sb.append(getOctet(i));
            if( i!= 0) sb.append(".");
        }

        return sb.toString();

    }

    @Override
    public boolean equals(Object obj) {
        if( obj instanceof IPAddress ) {
            return value==((IPAddress)obj).value;
        }
        return false;
    }

    @Override
    public int hashCode() {
        return value;
    }

    public int getValue() {
        return value;
    }

    public IPAddress next() {
        return new IPAddress(value+1);
    }


}

public class App13792784 {

    /**
     * @param args
     */
    public static void main(String[] args) {


        IPAddress ip1 = new IPAddress("192.168.0.1");

        System.out.println("ip1 = " + ip1);

        IPAddress ip2 = new IPAddress("192.168.0.255");

        System.out.println("ip2 = " + ip2);

        System.out.println("Looping:");

        do {

            ip1 = ip1.next();

            System.out.println(ip1);

        } while(!ip1.equals(ip2));


    }

}

看起来正是我所需要的。等我开始实现后再回报。 - Matt
@Brian,但是你认为交换的代码在哪里呢?例如,构造函数代码没有进行任何交换:IP地址的最左边部分(192)进入parts数组的最左边部分(part[0]),然后进入值的最左边部分(& 0xFF000000)。最左边的始终保持最左边,没有交换。 - Dims
Dims,我遇到了麻烦,因为我需要你的代码返回的IP地址是一个字符串。我该如何从你的代码中获取新的IP地址并将其转换为字符串类型返回? - Matt
Dims,你是个天才,不要让任何人告诉你相反!谢谢。 - Matt
@Dims 这非常有用,但我正在尝试理解代码为什么会被编写成这样,特别是构造函数。你为什么要向字符串解析器添加像 & 0xFF000000 这样的部分?如果只是字节移位和加法,你的代码难道不能运行吗?从我的测试来看,似乎这样就可以了。我只是想了解你的方法背后所做的决定。 - LordZardeck
显示剩余5条评论

1
如果您需要打印从IP + 0...255的所有内容。
public void iterateOverIPRange(String ip) {
    int i = 0;
    while(i < 256) {
        System.out.println(ip + "." + i)
        i++;
    }
}

或者如果您需要从0到255:

public String[] iterateOverIPRange(String ip) {
    String[] ips = new ip[255];
    int i = 0;
    while(i < 256)) {
        String s = ip + "." + i;
        ips[i] = s;
        i++;
    }
    return ips;
}

如果您想要指定范围:
public String[] iterateOverIPRange(String ip, int from, int to) {
    String[] ips = new ip[to];
    int index = 0;
    while(from < (to + 1)) {
        String s = ip + "." + from;
        ips[index] = s;
        from++;
        index++;
    }
    return ips;
}

当你有一个String[]时,你可以简单地遍历它并ping每一个项。

我认为FromTo192.168.0.1192.168.0.255只是OP给出的一个例子。 - adarshr
好的,现在应该可以为所有三个事物遇到了。 - OmniOwl
我不确定这些是否适合。我觉得我表达不清楚 :(. 用户输入起始地址和结束地址,我需要一种方法在该范围内循环所有地址。但是,我面临的问题是起始地址和结束地址都是字符串。我需要一种方法来遍历中间的每个地址... - Matt
你只需要将基础IP作为字符串(前三部分),然后将最后一部分作为整数。我相信你可以很容易地更改它。即使你不能,这些方法中的任何一个都应该很容易更改以适应你的需求。如果你需要从字符串中提取整数,可以使用Integer.parseInt(String)。只要记住,如果它没有得到可解析的整数,它将抛出未经检查的NumberFormatException异常。 - OmniOwl

0

由于我不喜欢位移,所以我为一次漏洞扫描器制作了自己的IP迭代结构。

目前的代码只会打印地址和一个额外的点。如果你取消ping实用程序或端口扫描器的注释,它也可以正常工作。

对于一些不太优化的变量名称和广泛异常表示抱歉,我是在记忆中编写的,没有使用更整洁的类。这只是为了表明Java使我们能够迭代通过更大范围的IP,而不使用位移。

package com.cybergrinder.core;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class ScanClient {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    try {
        // get input from somewhere, in this case we use the scanner for convenience and testing
        // try for example with 192.0.0.0 and 192.255.255.255 to scan the entire 192-B ranges
        Scanner scanner = new Scanner(System.in);
        System.out.println("start part of the address");
        String rangeStart = scanner.nextLine();
        System.out.println("end part of the address");
        String rangeEnd = scanner.nextLine();

        int[] startAdrElements = new int[4];
        int[] endAdrElements = new int[4];

        // System.out.println(rangeStart.split("\\.")[0]);

        int startA1 = (Integer.parseInt(rangeStart.split("\\.")[0]));
        int startB1 = (Integer.parseInt(rangeStart.split("\\.")[1]));
        int startC1 = (Integer.parseInt(rangeStart.split("\\.")[2]));
        int startD1 = (Integer.parseInt(rangeStart.split("\\.")[3]));
        int endA = (Integer.parseInt(rangeEnd.split("\\.")[0]));
        int endB = (Integer.parseInt(rangeEnd.split("\\.")[1]));
        int endC = (Integer.parseInt(rangeEnd.split("\\.")[2]));
        int endD = (Integer.parseInt(rangeEnd.split("\\.")[3]));

        int a = 0, b = 0, c = 0, d = 0; // args to work with after itteration proces
        for (int startA = startA1; startA <= endA; startA++) {// max 255.255.255.255, could implement sanitisation later..

            a = startA;

            for (int startB = startB1; startB <= endB; startB++) {

                b = startB;

                for (int startC = startC1; startC <= endC; startC++) {

                    c = startC;

                    for (int startD = startD1; startD <= endD; startD++) {

                        d = startD;

                        // convert intArray to byteArray
                        int[] intArray = new int[] { a, b, c, d };
                        String address = "";
                        for (int e : intArray) {
                            address += e + ".";
                        }

                        try {
                            System.out.println(address);

                            // enable pinging
                            /*
                            address = address.substring(0, (address.length() - 1));
                            InetAddress ipBytes = InetAddress.getByName(address);
                            boolean up = false;
                            up = ipBytes.isReachable(500);

                            if (up == true) {
                                System.out.println("host at " + ipBytes + " is up");
                            }
                            */

                            // enable portscanning
                            /*
                             * int port = 80; Socket sock = new Socket();
                             * sock.connect(new InetSocketAddress(ipBytes,
                             * port), 2000); //if it does not connect flow
                             * goes to catch System.out.println(port +"/tcp"
                             * + " is open ");
                             */

                        } catch (Exception e) {

                            // e.printStackTrace(); System.out.println("host
                            // is down");

                        }

                    }
                }
            }
        }

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } finally {
    }

}
}

0

只是简单的逻辑。我们可以使用以下逻辑(0.0.0.0 - 255.255.255.255)生成多达40亿(4228250625)个IP地址。

public class IpGenerator {
    public static void main(String[] args) throws Exception {
        int totalIP = 50000;//Set the total IPs to be generated
        String startIP= "10.10.1.1"; // Set the IP start range
        int A = Integer.parseInt(startIP.split("\\.")[0]);
        int B = Integer.parseInt(startIP.split("\\.")[1]);
        int C = Integer.parseInt(startIP.split("\\.")[2]);
        int D = Integer.parseInt(startIP.split("\\.")[3]);
        int total=0;
        while (total<=totalIP) {
            total++;
            if(255>D) {D++;}
            else {D=0;
                if(255>C) {C++;}
                else {C=0;
                    if(255>B) {B++;}
                    else {B=0;
                        if(255>A) {A++;}
                        else {
                            throw new Exception("IP LIMIT EXCEEDED !!!!!");
                        }
                    }
                }
            }
            String IP=A+"."+B+"."+C+"."+D;
            System.out.println("IP:"+IP);
        }
    }
}
Sample 
--------
...............
...............
...............
IP:10.10.193.251
IP:10.10.193.252
IP:10.10.193.253
IP:10.10.193.254
IP:10.10.193.255
IP:10.10.194.0
IP:10.10.194.1
IP:10.10.194.2
IP:10.10.194.3
IP:10.10.194.4
...............
...............
...............

-1

只需将末位数字变为整数,并随着进程递增即可。

public String strIp = "192.168.0.";
public Sting ip;

for (int x = 1; x == 255, x++) {
    ip = strIp+x;
}

我认为FromTo被给定为192.168.0.1192.168.0.255只是问题提出者举的例子。 - adarshr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接