从给定的IP地址和子网掩码中获取所有IP地址

Man*_*odi 6 java ip network-programming

在Java中,我需要获取给定IP网络包含的所有IP地址的列表.

例如,让netowork为:192.168.5.0/24,那么输出将是(192.168.5.0 ... 192.168.5.255).

我可以想到以下方式,但看起来很脏,有什么优雅的方式吗?InetAddress课堂上没有相同的功能.

  1. 从输入Ip和子网掩码中获取Network Ip.

    mask = (long)(0xffffffff) << (32-subnetMask);
    Long netIp = getLongfromIp(Inputip)& mask;
    
    Run Code Online (Sandbox Code Playgroud)

函数'getLongfromIp'包含以下代码 - 如何在Java中将字符串(IP号)转换为Integer

  1. 通过子网掩码获取主机数量

    maxRange = (long)0x1<<(32-subnetMask);

  2. 通过for i in (0 .. maxRange)在netIp中添加i 来获取所有希望的地址

  3. 将ip从上面的步骤转换为八位字符串.

Ps:我确定IP地址只能在IPV4中.

Man*_*odi 5

回答我自己的问题,解决方案是使用Apache commons.net

import org.apache.commons.net.util.*;

SubnetUtils utils = new SubnetUtils("192.168.1.0/24");
String[] allIps = utils.getInfo().getAllAddresses();
//appIps will contain all the ip address in the subnet
Run Code Online (Sandbox Code Playgroud)

阅读更多:Class SubnetUtils.SubnetInfo


Sea*_*n F 5

IPAddress Java 库以多态方式支持 IPv4 和 IPv6 子网。免责声明:我是项目经理。

以下示例代码用于透明地列出 IPv4 或 Ipv6 子网的地址。子网会变得非常大,尤其是在 IPv6 中,尝试遍历大型子网是不明智的,因此 iterateEdges 的代码显示了如何仅遍历子网中的开始地址和结束地址。

show("192.168.10.0/24");
show("2001:db8:abcd:0012::/64");

static void show(String subnet) throws AddressStringException {
    IPAddressString addrString = new IPAddressString(subnet);
    IPAddress addr = addrString.toAddress();
    show(addr);
}

static void show(IPAddress subnet) {
    Integer prefixLength = subnet.getNetworkPrefixLength();
    if(prefixLength == null) {
        prefixLength = subnet.getBitCount();
    }
    IPAddress mask = subnet.getNetwork().getNetworkMask(prefixLength, false);
    BigInteger count = subnet.getCount();
    System.out.println("Subnet of size " + count + " with prefix length " + prefixLength + " and mask " + mask);
    System.out.println("Subnet ranges from " + subnet.getLower() + " to " + subnet.getUpper());
    int edgeCount = 3;
    if(count.compareTo(BigInteger.valueOf(256)) <= 0) {
        iterateAll(subnet, edgeCount);
    } else {
        iterateEdges(subnet, edgeCount);
    }
}
Run Code Online (Sandbox Code Playgroud)

遍历整个子网,谨慎使用:

static void iterateAll(IPAddress subnet, int edgeCount) {
    BigInteger count = subnet.getCount();
    BigInteger bigEdge = BigInteger.valueOf(edgeCount), currentCount = count;
    int i = 0;
    for(IPAddress addr: subnet.getIterable()) {
        currentCount = currentCount.subtract(BigInteger.ONE);
        if(i < edgeCount) {
            System.out.println(++i + ": " + addr);
        } else if(currentCount.compareTo(bigEdge) < 0) {
            System.out.println(count.subtract(currentCount) + ": " + addr);
        } else if(i == edgeCount) {
            System.out.println("...skipping...");
            i++;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

遍历子网边缘:

static void iterateEdges(IPAddress subnet, int edgeCount) {
    for(int increment = 0; increment < edgeCount; increment++) {
        System.out.println((increment + 1) + ": " + subnet.getLower().increment(increment));
    }
    System.out.println("...skipping...");
    BigInteger count = subnet.getCount();
    for(int decrement = 1 - edgeCount; decrement <= 0; decrement++) {
        System.out.println(count.add(BigInteger.valueOf(decrement)) + ": " + subnet.getUpper().increment(decrement));
    }
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

Subnet of size 256 with prefix length 24 and mask 255.255.255.0
Subnet ranges from 192.168.5.0/24 to 192.168.5.255/24
1: 192.168.5.0/24
2: 192.168.5.1/24
3: 192.168.5.2/24
...skipping...
254: 192.168.5.253/24
255: 192.168.5.254/24
256: 192.168.5.255/24

Subnet of size 18446744073709551616 with prefix length 64 and mask ffff:ffff:ffff:ffff::
Subnet ranges from 2001:db8:abcd:12::/64 to 2001:db8:abcd:12:ffff:ffff:ffff:ffff/64
1: 2001:db8:abcd:12::/64
2: 2001:db8:abcd:12::1/64
3: 2001:db8:abcd:12::2/64
...skipping...
18446744073709551614: 2001:db8:abcd:12:ffff:ffff:ffff:fffd/64
18446744073709551615: 2001:db8:abcd:12:ffff:ffff:ffff:fffe/64
18446744073709551616: 2001:db8:abcd:12:ffff:ffff:ffff:ffff/64
Run Code Online (Sandbox Code Playgroud)

  • 人们懒得读你真正好的答案......你必须更简短:) (2认同)