import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String subnetMask = sc.nextLine();//子网掩码 String IPOne = sc.nextLine(); String IPTwo = sc.nextLine(); //若IP地址或子网掩码格式非法则输出1,若IP1与IP2属于同一子网络输出0,若IP1与IP2不属于同一子网络输出2 //1.检验IP地址和子网掩码是否都是合法的 if(isValidIPAddress(IPOne)&&isValidIPAddress(IPTwo)&&isValidMask(subnetMask)){//合法 //2.判断是否同一子网 if(isSameSubnet(IPOne,IPTwo,subnetMask)){//属于同一子网 System.out.println(0); }else {//不属于同一子网 System.out.println(2); } }else {//非法 System.out.println(1); } } //判断两个IP地址是否属于同一子网 private static boolean isSameSubnet(String ipOne, String ipTwo, String subnetMask) { String[] sMask = subnetMask.split("\\."); String[] ipO = ipOne.split("\\."); String[] ipT = ipTwo.split("\\."); Boolean Flag = true; for (int i = 0; i < 4; i++) {//地址分4段转换成2进制, if(isSameResult(sMask[i],ipO[i],ipT[i])){ Flag = true; }else { Flag = false; break; } } return Flag; } //地址分4段转换成2进制,每一段在这个方法中进行“与运算”,再比较。 private static boolean isSameResult(String sMaskQuarter, String ipOQuarter, String ipTQuarter) { String[] Quarter = {sMaskQuarter,ipOQuarter,ipTQuarter};//保存这三个十进制数:子网掩码、IP地址一、IP地址二。 StringBuilder[] strBinary = new StringBuilder[3];//转换成三个二进制字符串 for (int i = 0; i < 3; i++) { Quarter[i] = Integer.toBinaryString(Integer.parseInt(Quarter[i]));//字符串转换成整数int型,再转换成二进制数的字符串。 StringBuilder str = new StringBuilder(); if(Quarter[i].length()<8){//检查不足8位数,要补足8位 for (int j = 0; j < 8-Quarter[i].length(); j++) { //先在空字符串中补0 str.append("0"); }//然后在后面加上二进制数的字符串 strBinary[i] = str.append(Quarter[i]); }else {//正好8位数(//等于255可以确定二进制字符串最多只有8位。) strBinary[i] = str.append(Quarter[i]); } } //将三个二进制字符串按位与运算,得到两行与运算之后的结果。 char[] M = String.valueOf(strBinary[0]).toCharArray(); char[] IP1 = String.valueOf(strBinary[1]).toCharArray(); char[] IP2 = String.valueOf(strBinary[2]).toCharArray(); Boolean Flag = true; for (int i = 0; i < 8; i++) { if((String.valueOf(M[i]&IP1[i])).equals(String.valueOf(M[i]&IP2[i]))){ Flag = true; }else { Flag = false; break; } } return Flag; } //检验ip地址是否合法 private static boolean isValidIPAddress (String ip){ String[] ipTable = ip.split("\\."); if(ipTable.length != 4){//四位 return false; }else { for (String s : ipTable){//小于255可以确定二进制字符串最多只有8位。 if (Integer.parseInt(s)<0 || Integer.parseInt(s)>255){ return false; } } return true; } } /*子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码) (注意二进制下全是1或者全是0均为非法子网掩码)*/ //检验掩码是否合法 public static boolean isValidMask(String mask){ /*if(s[1]=="255.255.255.255"||s[1]=="0.0.0.0"){ num[5]++; continue; }*/ /* 子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码) (注意二进制下全是1或者全是0均为非法子网掩码)*/ if(!isValidIPAddress(mask)){//检验IP地址的掩码,首先检验IP地址是否合法的。 return false; } else if (mask=="255.255.255.255"||mask=="0.0.0.0") {//(注意二进制下全是1或者全是0均为非法子网掩码) return false; } else {//检验IP地址的掩码是否是连续的1,然后全是0 String[] maskTable = mask.split("\\."); StringBuilder strBuilder = new StringBuilder();//得到32位32位无符号字符编码,即掩码字符串 for (int i = 0; i < maskTable.length; i++) { maskTable[i] = Integer.toBinaryString(Integer.parseInt(maskTable[i]));//字符串转换成整数int型,再转换成二进制数的字符串。 if(maskTable[i].length()<8){//检查不足8位数,要补足8位 for (int j = 0; j < 8-maskTable[i].length(); j++) { strBuilder.append("0");//先在空字符串中补0 }//然后在后面加上二进制数的字符串 strBuilder.append(maskTable[i]); }else {//正好8位数(//小于255可以确定二进制字符串最多只有8位。) strBuilder.append(maskTable[i]); } } /*找到32位无符号字符编码中,第一个0的位置和最后一个1的位置,如果最后一个1的位置+1得到第一个零的位置。 代表这是一段连续的1,后面拼接了一段连续的0。*/ if(strBuilder.lastIndexOf("1")+1==strBuilder.indexOf("0")){ return true;//是连续的1,然后全是0 }else{ return false; } } } }
修改版:
import java.util.Scanner; // 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String subnetMask = sc.nextLine();//子网掩码 String IPOne = sc.nextLine(); String IPTwo = sc.nextLine(); //若IP地址或子网掩码格式非法则输出1,若IP1与IP2属于同一子网络输出0,若IP1与IP2不属于同一子网络输出2 //1.检验IP地址和子网掩码是否都是合法的 if (isValidIPAddress(IPOne) && isValidIPAddress(IPTwo) && isValidMask(subnetMask)) {//合法 //2.判断两个IP地址是否属于同一子网Mask String[] sMask = subnetMask.split("\\."); String[] ipO = IPOne.split("\\."); String[] ipT = IPTwo.split("\\."); Boolean Flag = true; for (int i = 0; i < 4; i++) {//掩码和地址都分4段转换成2进制,并进行与运算比较是否一致。 if (isSameResult(sMask[i], ipO[i], ipT[i])) { Flag = true; } else { Flag = false; break; } } if (Flag) {//属于同一子网 System.out.println(0); } else {//不属于同一子网 System.out.println(2); } } else {//非法 System.out.println(1); } } //地址分4段转换成2进制,每一段在这个方法中进行“与运算”,再比较。 private static boolean isSameResult(String sMaskQuarter, String ipOQuarter, String ipTQuarter) { String[] Quarter = {sMaskQuarter, ipOQuarter, ipTQuarter};//保存这三个十进制数:子网掩码、IP地址一、IP地址二。 StringBuilder[] strBinary = new StringBuilder[3];//转换成三个二进制字符串 for (int i = 0; i < 3; i++) { strBinary[i] = ConvertDecimalToABinary8_bit(Quarter[i]); } //将三个二进制字符串按位与运算,得到两行与运算之后的结果。 char[] M = String.valueOf(strBinary[0]).toCharArray(); char[] IP1 = String.valueOf(strBinary[1]).toCharArray(); char[] IP2 = String.valueOf(strBinary[2]).toCharArray(); Boolean Flag = true; for (int i = 0; i < 8; i++) { if ((String.valueOf(M[i] & IP1[i])).equals(String.valueOf(M[i] & IP2[i]))) { Flag = true; } else { Flag = false; break; } } return Flag; } //检验ip地址是否合法 private static boolean isValidIPAddress(String ip) { String[] ipTable = ip.split("\\."); if (ipTable.length != 4) {//四位 return false; } else { for (String s : ipTable) {//小于255可以确定二进制字符串最多只有8位。 if (Integer.parseInt(s) < 0 || Integer.parseInt(s) > 255) { return false; } } return true; } } /*子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码) (注意二进制下全是1或者全是0均为非法子网掩码)*/ //检验掩码是否合法 public static boolean isValidMask(String mask) { /* 子网掩码为二进制下前面是连续的1,然后全是0。(例如:255.255.255.32就是一个非法的掩码) (注意二进制下全是1或者全是0均为非法子网掩码)*/ if (!isValidIPAddress(mask)) {//检验IP地址的掩码,首先检验IP地址是否合法的。 return false; } else if (mask == "255.255.255.255" || mask == "0.0.0.0") {//(注意二进制下全是1或者全是0均为非法子网掩码) return false; } else {//检验IP地址的掩码是否是连续的1,然后全是0 String[] maskTable = mask.split("\\."); StringBuilder strBuilder = new StringBuilder();//得到32位32位无符号字符编码,即掩码字符串 for (int i = 0; i < maskTable.length; i++) { strBuilder.append(ConvertDecimalToABinary8_bit(maskTable[i])); } /*找到32位无符号字符编码中,第一个0的位置和最后一个1的位置,如果最后一个1的位置+1得到第一个零的位置。 代表这是一段连续的1,后面拼接了一段连续的0。*/ if (strBuilder.lastIndexOf("1") + 1 == strBuilder.indexOf("0")) { return true;//是连续的1,然后全是0 } else { return false; } } } //将十进制数字转换成二进制8位字符串。 public static StringBuilder ConvertDecimalToABinary8_bit(String str) { StringBuilder strB = new StringBuilder(); str = Integer.toBinaryString(Integer.parseInt(str));//字符串转换成整数int型,再转换成二进制数的字符串。 if (str.length() < 8) {//检查不足8位数,要补足8位 for (int j = 0; j < 8 - str.length(); j++) { strB.append("0");//先在空字符串中补0 }//然后在后面加上二进制数的字符串 } return strB.append(str); } }