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"; } } |