IPアドレスの範囲チェックを行う(Java) †IPアドレスの範囲チェックのサンプルを探してみたら Apache James 等のライブラリを使用する例しか見つからなかったので、 スクラッチで組んでみたらどうなるかやってみた。 チェッククラス †package example;
public class CheckIpAddress {
/**
* IPアドレスがプライベートIPかどうかをチェックする。<br />
* @param checkIp チェックするIPアドレス
* @return true:プライベートIP、false:プライベートIPではない
*/
public static boolean isPrivateIpAddres(String checkIp){
if (chekRangeIpAddress(checkIp, "10.0.0.0", "10.255.255.255")
|| chekRangeIpAddress(checkIp, "172.16.0.0", "172.31.255.255")
|| chekRangeIpAddress(checkIp, "192.168.0.0", "192.168.255.255")){
return true;
}
return false;
}
/**
* IPアドレスが指定された範囲ないかどうかをチェックする。<br />
* @param checkIp チェックするIPアドレス
* @param firstIp 先頭IPアドレス
* @param lastIp 最終IPアドレス
* @return true:範囲内、false:範囲外
*/
public static boolean chekRangeIpAddress(String checkIp, String firstIp, String lastIp){
// 桁数揃え
checkIp = formatIp(checkIp);
firstIp = formatIp(firstIp);
lastIp = formatIp(lastIp);
// 整形できない場合はエラー
if (checkIp == null || firstIp == null || lastIp == null) {
return false;
}
// 範囲内かチェック
if (checkIp.compareTo(firstIp) < 0 || checkIp.compareTo(lastIp) > 0) {
return false;
}
return true;
}
/**
* IPアドレスの桁数を揃える(各セグメントを3桁に揃える)
* @param ip IPアドレス
* @return 整形後のIPアドレス
*/
public static String formatIp(String ip){
// 4つに分割できない時はエラー
String[] ipArray = ip.split("\\.");
if (ipArray.length != 4) {
return null;
}
// 数値とピリオド以外にマッチした場合はエラー
for (int i = 0; i < 4; i++) {
String ipPart = ipArray[i];
if (ipPart == null || ipPart.isEmpty() || (ipPart.matches("[^0-9]"))){
return null;
}
}
// 3桁に満たない場合は3桁にする
for (int i = 0; i < 4; i++){
int len = ipArray[i].length();
for (int j = len; j < 3; j++) {
ipArray[i] = "0" + ipArray[i];
}
}
// 3桁*4のIPを組立
String delimiter = "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 4; i++){
sb.append(delimiter);
sb.append(ipArray[i]);
delimiter = ".";
}
return sb.toString();
}
}
確認用コード †※ 注意)環境にもよると思うが、全IPをチェックしようと思ったら8時間ぐらいかかる。 package example;
import java.util.Date;
public class CopyOfCheckIpAddressTest {
// 個別チェック用
//public static void main(String[] args) {
//
// boolean res = CheckIpAddress.chekRangeIpAddress("172.30.255.255", "172.30.200.255", "172.31.200.255");
// System.out.println(res);
//}
public static void main(String[] args) {
System.out.println("Start ... " + new Date());
long[] result0 = checkPrivateIp("0.0.0.0" , "9.255.255.255" , false); //
long[] result1 = checkPrivateIp("10.0.0.0" , "10.255.255.255" , true); // クラスA
long[] result2 = checkPrivateIp("11.0.0.0" , "171.255.255.255" , false); //
long[] result3 = checkPrivateIp("172.16.0.0" , "172.31.255.255" , true); // クラスB
long[] result4 = checkPrivateIp("172.32.0.0" , "192.167.255.255" , false); //
long[] result5 = checkPrivateIp("192.168.0.0" , "192.168.255.255" , true); // クラスC
long[] result6 = checkPrivateIp("192.169.0.0" , "255.255.255.255" , false); //
long okCntAll = result0[0] + result1[0] + result2[0] + result3[0] + result4[0] + result5[0] + result6[0];
long ngCntAll = result0[1] + result1[1] + result2[1] + result3[1] + result4[1] + result5[1] + result6[1];
System.out.println("チェック件数 : " + (okCntAll + ngCntAll));
System.out.println("正常件数 : " + okCntAll);
System.out.println("エラー件数 : " + ngCntAll);
if (ngCntAll == 0) {
System.out.println("エラーなし");
} else {
System.err.println("エラーあり!!!");
}
System.out.println("End ... " + new Date());
}
/**
* プライベートIPアドレスかどうかをチェックする
* @param fstIp チェックするIPの開始値
* @param lastIp チェックするIPの最終値
* @param expected 期待値(true:プライベートIP)
* @return [チェックOK件数、チェックエラー件数]
*/
private static long[] checkPrivateIp(String fstIp, String lastIp, boolean expected){
System.out.println("チェック開始 : " + fstIp + " - " + lastIp);
String[] fstIpAry = fstIp.split("\\.");
String[] lastIpAry = lastIp.split("\\.");
if ((fstIpAry.length != 4) || (lastIpAry.length != 4)) {
throw new RuntimeException("引数が誤っています(" + fstIp + "," + lastIp + ")");
}
long okCnt = 0;
long ngCnt = 0;
String checkIp = fstIp;
while (ipCompareTo(checkIp, lastIp) <= 0) {
boolean result = CheckIpAddress.isPrivateIpAddres(checkIp);
if (result == expected) {
okCnt++;
//System.out.println("期待値する結果です\t" + checkIp + "\t期待値:" + expected + "\t結果:" + result );
} else {
ngCnt++;
System.err.println("期待値と異なります!\t" + checkIp + "\t期待値:" + expected + "\t結果:" + result );
}
checkIp = nextIp(checkIp);
}
System.out.println("チェック終了 : " + fstIp + " - " + lastIp);
return new long[]{okCnt, ngCnt};
}
/**
* IPアドレスの大小比較
* @param checkIp IPアドレス1
* @param compareIp IPアドレス2
* @return 比較結果
*/
private static int ipCompareTo(String checkIp, String compareIp){
checkIp = CheckIpAddress.formatIp(checkIp);
compareIp = CheckIpAddress.formatIp(compareIp);
return checkIp.compareTo(compareIp);
}
/**
* 次のIPアドレスを取得する。
* @param checkIp IPアドレス
* @return 次のIPアドレス
*/
private static String nextIp(String ip){
String[] ipArray = ip.split("\\.");
for (int i = 3; i >= 0; i--) {
int ipPart = Integer.parseInt(ipArray[i]);
if (ipPart < 255){
ipArray[i] = String.valueOf(++ipPart);
return ipArray[0] + "." + ipArray[1] + "." + ipArray[2] + "." + ipArray[3];
} else {
ipArray[i] = "0";
}
}
return "255.255.255.256";
}
}
|