初めに
クラウドのサーバを使用することになり、ありがたくもグローバルIPを頂けることになった。社内PC(プライベートIP)とクラウドサーバ(グローバルIP)で処理を切り分けるために、IPからアドレスクラスとプライベートIPかを判断できるようにした。
(元ネタ)
IPアドレスからアドレスクラスとアドレスの種類を求める with Java
(参考)
IPアドレス - Wikipedia
実装
IPAddressInfo.java
public class IPAddressInfo {
public enum AddressClass{
ClassA(128) {
@Override
protected boolean isPrivate(int first, int second) {
return first == 10;
}
},
ClassB(128 + 64) {
@Override
protected boolean isPrivate(int first, int second) {
return first == 172 && (16 <= second && second <= 31);
}
},
ClassC(128 + 64 + 32) {
@Override
protected boolean isPrivate(int first, int second) {
return first == 192 && second == 168;
}
},
ClassD(128 + 64 + 32 + 16) {
@Override
protected boolean isPrivate(int first, int second) {
return false;
}
},
ClassE(256) {
@Override
protected boolean isPrivate(int first, int second) {
return false;
}
},;
private final int outOfNo;
/**
* IPアドレスの5つのアドレスクラス。
* @param outOfNo 次のアドレスクラスのIPの1つめ
*/
private AddressClass(int outOfNo){
this.outOfNo = outOfNo;
}
protected abstract boolean isPrivate(int first, int second);
}
public AddressClass getAddressClass(int first){
return Arrays.stream(AddressClass.values()).filter(p -> first < p.outOfNo).findFirst().orElseThrow(() -> new IllegalArgumentException("IPでない:" + first));
}
public AddressClass getAddressClass(String ip){
List<String> addressList = Arrays.asList(ip.split("\\."));
return getAddressClass(Integer.valueOf(addressList.get(0)));
}
public boolean isPrivate(String ip){
List<String> addressList = Arrays.asList(ip.split("\\."));
int first = Integer.valueOf(addressList.get(0));
int second = Integer.valueOf(addressList.get(1));
return getAddressClass(first).isPrivate(first, second);
}
}
テスト
IPAddressInfo.java
@Test
public void getAddressClass(){
assertThat(getAddressClass("0.0.0.0"), is(AddressClass.ClassA));
assertThat(getAddressClass("10.0.0.0"), is(AddressClass.ClassA));
assertThat(getAddressClass("10.255.255.255"), is(AddressClass.ClassA));
assertThat(getAddressClass("127.255.255.255"), is(AddressClass.ClassA));
assertThat(getAddressClass("128.0.0.0"), is(AddressClass.ClassB));
assertThat(getAddressClass("172.16.0.0"), is(AddressClass.ClassB));
assertThat(getAddressClass("172.31.255.255"), is(AddressClass.ClassB));
assertThat(getAddressClass("191.255.255.255"), is(AddressClass.ClassB));
assertThat(getAddressClass("192.0.0.0"), is(AddressClass.ClassC));
assertThat(getAddressClass("192.168.0.0"), is(AddressClass.ClassC));
assertThat(getAddressClass("192.168.255.255"), is(AddressClass.ClassC));
assertThat(getAddressClass("223.255.255.255"), is(AddressClass.ClassC));
assertThat(getAddressClass("224.0.0.0"), is(AddressClass.ClassD));
assertThat(getAddressClass("239.255.255.255"), is(AddressClass.ClassD));
assertThat(getAddressClass("240.0.0.0"), is(AddressClass.ClassE));
assertThat(getAddressClass("255.255.255.255"), is(AddressClass.ClassE));
}
@Test
public void isPrivate(){
assertThat(isPrivate("0.0.0.0"), is(false));
assertThat(isPrivate("10.0.0.0"), is(true));
assertThat(isPrivate("10.255.255.255"), is(true));
assertThat(isPrivate("127.255.255.255"), is(false));
assertThat(isPrivate("128.0.0.0"), is(false));
assertThat(isPrivate("172.16.0.0"), is(true));
assertThat(isPrivate("172.31.255.255"), is(true));
assertThat(isPrivate("191.255.255.255"), is(false));
assertThat(isPrivate("192.0.0.0"), is(false));
assertThat(isPrivate("192.168.0.0"), is(true));
assertThat(isPrivate("192.168.255.255"), is(true));
assertThat(isPrivate("223.255.255.255"), is(false));
assertThat(isPrivate("224.0.0.0"), is(false));
assertThat(isPrivate("239.255.255.255"), is(false));
assertThat(isPrivate("240.0.0.0"), is(false));
assertThat(isPrivate("255.255.255.255"), is(false));
}
@Test(expected=IllegalArgumentException.class)
public void error(){
getAddressClass("256.255.255.255");
}