在Java中,我需要获取给定IP网络包含的所有IP地址的列表。
例如让netowork为:192.168.5.0/24然后输出将是(192.168.5.0 ... 192.168.5.255)。
我可以想到以下方式,但它看起来很脏,有没有优雅的方式? InetAddress
类中没有相同的功能。
从输入IP和子网掩码中获取网络IP。
mask = (long)(0xffffffff) << (32-subnetMask);
Long netIp = getLongfromIp(Inputip)& mask;
函数'getLongfromIp'包含来自 - How to convert string (IP numbers) to Integer in Java
的代码通过子网掩码获取主机数
maxRange = (long)0x1<<(32-subnetMask);
通过在netIp中添加for i in (0 .. maxRange)
来获取所有希望的地址
将ip从上一步转换为八位字符串。
Ps:我确定IP地址只能在IPV4中。
答案 0 :(得分: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
答案 1 :(得分:1)
包含NetworkAddress和BroadcastAddress
import org.apache.commons.net.util.*;
SubnetUtils utils = new SubnetUtils("192.168.1.0/28");
utils.setInclusiveHostCount(true);
String[] allIps = utils.getInfo().getAllAddresses();
答案 2 :(得分:0)
The IPAddress Java library以一种多态的方式同时支持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);
System.out.println();
}
static void show(IPAddress subnet) {
Integer prefix = subnet.getNetworkPrefixLength();
IPAddress mask = subnet.getNetwork().getNetworkMask(prefix, false);
BigInteger count = subnet.getCount();
System.out.println("Subnet of size " + count + " with prefix length " + prefix + " and mask " + mask);
System.out.println("Subnet ranges from " + subnet.getLower() + " to " + subnet.getUpper());
if(count.compareTo(BigInteger.valueOf(256)) <= 0) {
iterateAll(subnet);
} else {
iterateEdges(subnet);
}
}
static void iterateAll(IPAddress subnet) {
BigInteger count = subnet.getCount();
BigInteger three = BigInteger.valueOf(3), currentCount = count;
int i = 0;
for(IPAddress addr: subnet.getIterable()) {
if(i < 3) {
System.out.println(++i + ": " + addr);
} else if(currentCount.compareTo(three) <= 0) {
System.out.println(count.subtract(currentCount) + ": " + addr);
} else if(i == 3) {
System.out.println("...skipping...");
i++;
}
currentCount = currentCount.subtract(BigInteger.ONE);
}
}
static void iterateEdges(IPAddress subnet) {
int sample = 3;
for(int i = -sample; i < sample; i++) {
if(i < 0) {
int increment = i + sample + 1;
System.out.println(increment + ": " + subnet.getLower().increment(increment - 1));
} else {
if(i == 0) {
System.out.println("...skipping...");
}
BigInteger count = subnet.getCount();
int increment = i - sample + 1;
System.out.println(count.add(BigInteger.valueOf(increment)) + ": " + subnet.getUpper().increment(increment));
}
}
}
以下是输出:
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...
253: 192.168.5.253/24
254: 192.168.5.254/24
255: 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
如果您以地址开头,则可以使用toPrefixBlock()获取子网:
IPAddress addr = new IPAddressString("192.168.5.1/24").toAddress();
IPAddress subnet = addr.toPrefixBlock();
System.out.println(addr + " is from subnet " + subnet);
输出:
192.168.5.1/24 is from subnet 192.168.5.0/24
答案 3 :(得分:0)
以下内容与使用https://seancfoley.github.io/IPAddress/的Sean的回答(非常好!)相同,只是降低了信噪比:
subnetToIps("192.168.10.0/28");
public void subnetToIps(String ipOrCidr) {
IPAddressString addrString = new IPAddressString(ipOrCidr, IPAddressString.DEFAULT_VALIDATION_OPTIONS);
IPAddress subnet = addrString.toAddress();
System.out.println("Subnet ranges from " + subnet.getLower() + " to " + subnet.getUpper());
int i = 0;
for (IPAddress addr : subnet.getIterable()) {
System.out.println(++i + ": " + addr);
}
}