IPアドレスからアドレスクラスとアドレスの種類を求める with Java【2番煎じ】

# 初めに
クラウドのサーバを使用することになり、ありがたくもグローバルIPを頂けることになった。社内PC(プライベートIP)とクラウドサーバ(グローバルIP)で処理を切り分けるために、IPからアドレスクラスとプライベートIPかを判断できるようにした。

(元ネタ)
[IPアドレスからアドレスクラスとアドレスの種類を求める with Java](https://qiita.com/Nobu12/items/211ffa773c1758578b1c)

(参考)
[IPアドレス - Wikipedia](https://ja.wikipedia.org/wiki/IP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9)

# 実装
```java: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);
	}
}
```

#テスト
```java: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");
	}
```