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

京公网安备 11010502036488号