題目描述
子網掩碼是用來判斷任意兩臺計算機的IP地址是否屬於同一子網絡的根據。
子網掩碼與IP地址結構相同,是32位二進制數,其中網絡號部分全爲「1」和主機號部分全爲「0」。利用子網掩碼能夠判斷
兩臺主機是否中同一子網中。若兩臺主機的IP地址分別與它們的子網掩碼相「與」後的結果相同,則說明這兩臺主機在同一子網中。
示例:
IP地址 192.168.0.1
子網掩碼 255.255.255.0
轉化爲二進制進行運算:
IP地址 11010000.10101000.00000000.00000001
子網掩碼 11111111.11111111.11111111.00000000
AND運算
11000000.10101000.00000000.00000000
轉化爲十進制後爲:
192.168.0.0
IP地址 192.168.0.254
子網掩碼 255.255.255.0
轉化爲二進制進行運算:
IP地址 11010000.10101000.00000000.11111110
子網掩碼 11111111.11111111.11111111.00000000
AND運算
11000000.10101000.00000000.00000000
轉化爲十進制後爲:
192.168.0.0
經過以上對兩臺計算機IP地址與子網掩碼的AND運算後,咱們能夠看到它運算結果是同樣的。均爲192.168.0.0,
因此這二臺計算機可視爲是同一子網絡。
/**
* 功能: 判斷兩臺計算機IP地址是同一子網絡。
* 輸入參數: String Mask: 子網掩碼,格式:「255.255.255.0」;
* String ip1: 計算機1的IP地址,格式:「192.168.0.254」;
* String ip2: 計算機2的IP地址,格式:「192.168.0.1」;
*
* 返回值:0:IP1與IP2屬於同一子網絡;
* 1:IP地址或子網掩碼格式非法;
* 2:IP1與IP2不屬於同一子網絡
*/
public int checkNetSegment(String mask, String ip1, String ip2) {
/*在這裏實現功能*/
return 0;
}
輸入描述
輸入子網掩碼、兩個ip地址
輸出描述
獲得計算結果
輸入例子
255.255.255.0
192.168.224.256
192.168.10.4
輸出例子
1
算法實現
import java.util.Scanner;
/**
* Declaration: All Rights Reserved !!!
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Scanner scanner = new Scanner(Main.class.getClassLoader().getResourceAsStream("data.txt"));
while (scanner.hasNext()) {
String subnet = scanner.next();
String ip1 = scanner.next();
String ip2 = scanner.next();
System.out.println(subnetJudgement(subnet, ip1, ip2));
}
scanner.close();
}
private static int subnetJudgement(String subnet, String ip1, String ip2) {
// 1:IP地址或子網掩碼格式非法
if (!ipValidate(subnet) || !ipValidate(ip1) || !ipValidate(ip2)) {
return 1;
}
int subnetInt = ipStrToInt(subnet);
// 1:子網掩碼格式非法
if (!subnetMaskValidate(subnetInt)) {
return 1;
}
int b = ipStrToInt(ip2);
int a = ipStrToInt(ip1);
// 0:IP1與IP2屬於同一子網絡
if ((a & subnetInt) == (b & subnetInt)) {
return 0;
}
// 2:IP1與IP2不屬於同一子網絡
else {
return 2;
}
}
/**
* 驗證IP地址的格式是否正確
*
* @param ip IP地址
* @return true:格式正確,false:格式不正確
*/
private static boolean ipValidate(String ip) {
String[] part = ip.split("\\.");
// if (part.length != 4) {
// return false;
// }
for (String s : part) {
try {
int num = Integer.parseInt(s);
if (num < 0 || num > 255) {
return false;
}
} catch (Exception ex) {
return false;
}
}
return true;
}
/**
* 子網掩碼驗證,網絡號部分全爲「1」和主機號部分全爲「0」
*
* @param ip
* @return
*/
private static boolean subnetMaskValidate(int ip) {
boolean hasZero = false;
int and = 0x80000000;
while (and != 0) {
// 所處理的位位置爲0
if ((ip & and) == 0) {
// 說明出現了0
hasZero = true;
}
// 若是位置爲1
else {
// 以前已經有0出現過,那說明1是不連續的,因此子網掩碼不合法
if (hasZero) {
return false;
}
}
// 無符號右移一位
and >>>= 1;
}
return true;
}
/**
* 將點分十進制的IP地址轉換成整數表示
*
* @param ip 點分十進制的IP地址
* @return IP地址的整數表
*/
private static int ipStrToInt(String ip) {
String[] part = ip.split("\\.");
int intIP = 0;
for (int i = 0; i < part.length; i++) {
int t = Integer.parseInt(part[i]);
intIP += t << (24 - 8 * i);
}
return intIP;
}
}