commons-netのSubnetUtilsを使って、サブネットワークから欲しいIPアドレスを抽出するやり方。
例えば、「サブネットワークの先頭5個」「サブネットワークのうち、まだ使用されていないものの先頭1個」というケースを想定。
0. CIDR表記からインスタンス生成
javadocが下記の通り、丁寧に書いてあります。
public SubnetUtils(String cidrNotation)
Constructor that takes a CIDR-notation string, e.g. "192.168.0.1/16"
Parameters:
cidrNotation - A CIDR-notation string, e.g. "192.168.0.1/16"
Throws:
IllegalArgumentException - if the parameter is invalid, i.e. does not match n.n.n.n/m where n=1-3 decimal digits, m = 1-3 decimal digits in range 1-32
つまり、下記のようにしてインスタンスが生成できるということ。
SubnetUtils subnet = new SubnetUtils("192.168.0.0/24");
subnet.getInfo()
の戻り値のSubnetUtils.SubnetInfo から、ネットワークの情報を引き出せます。
1. ネットワークアドレス
getNetworkAddress()
で取得できます。
SubnetUtils subnet = new SubnetUtils("192.168.0.0/24");
String networkAddress = subnet.getInfo().getNetworkAddress();
System.out.println(networkAddress);
192.168.0.0
2. ブロードキャストアドレス
getBroadcastAddress()
で取得できます。
SubnetUtils subnet = new SubnetUtils("192.168.0.0/24");
String broadcastAddress= subnet.getInfo().getBroadcastAddress();
System.out.println(broadcastAddress);
192.168.0.255
3. その他のアドレス
getAllAddresses()
で、使用できるアドレスを配列で取得できます。
SubnetUtils subnet = new SubnetUtils("192.168.0.0/30");
List<String> allAddresses= Arrays.asList(subnet.getInfo().getAllAddresses());
System.out.println(addAddresses);
[192.168.0.1,192.168.0.2]
4. アドレスの抽出
例1 サブネットワークの先頭5個
getAllAddresses()とsubListを組み合わせます。
SubnetUtils subnet = new SubnetUtils("192.168.0.0/24");
List<String> addresses= Arrays.asList(subnet.getInfo().getAllAddresses()).subList(0, 5);
System.out.println(addresses);
例2 サブネットワークのうち、まだ使用されていないものの先頭1個
使用済みのIPアドレスはDBから取得できるものとします。
コレクション操作のためにGuava を使います。(java7の仕事のときに編み出したので)
final List<String> usedAddresses = ...; //DBなどから取得
List<String> allAddresses= Arrays.asList(subnet.getInfo().getAllAddresses());
Predicate<String> isUnused = new Predicate<String>() {
public boolean apply(String address) {
return !usedAddresses.contains(address);
}
};
String unusedAddress = Iterables.find(allAddresses, isUnused, "");
まとめ
サブネットのアドレス全体を配列で取得できるので、除外したいものをリストで取得できれば、大抵の抽出はできそう。
車輪の再発明する気がないなら、このあたりを使うと楽。
java8なら、streamとlambda式でもう少しすっきり書けるはず。