要判斷兩個IP地址是不是在同一個網段,就將它們的IP地址分別與子網掩碼做與運算,得到的結果一網絡號,如果網絡號相同,就在同一子網,否則,不在同一子網。
例如:假定選擇了子網掩碼255.255.254.0,現在分別將上述兩個IP地址分別與掩碼做與運算,如下圖所示:
211.95.165.24 11010011 01011111 10100101 00011000
255.255.254.0 11111111 11111111 111111110 00000000
與的結果是: 11010011 01011111 10100100 00000000
211.95.164.78 11010011 01011111 10100100 01001110
255.255.254.0 11111111 11111111 111111110 00000000
與的結果是: 11010011 01011111 10100100 00000000
可以看出,得到的結果(這個結果就是網絡地址)都是一樣的,因此可以判斷這兩個IP地址在同一個子網。
例如:有一個C類地址爲:192.9.200.13,按其IP地址類型,它的缺省子網掩碼爲:255.255.255.0,則它的網絡號和主機號可按如下方法得到:
第1步,將IP地址192.9.200.13轉換爲二進制11000000 00001001 11001000 00001101
第2步,將子網掩碼255.255.255.0轉換爲二進制11111111 11111111 11111111 00000000
第3步,將以上兩個二進制數邏輯進行與(AND)運算,得出的結果即爲網絡部分。“11000000 00001001 11001000 00001101”與“11111111 11111111 11111111 00000000”進行“與”運算後得到“11000000 00001001 11001000 00000000”,即“192.9.200.0”,這就是這個IP地址的網絡號,或者稱“網絡地址”。
第4步,將子網掩碼的二進制值取反後,再與IP地址進行與(AND)運算,得到的結果即爲主機部分。如將“00000000 00000000 00000000 11111111(子網掩碼的取值)反”與“11000000 00001001 11001000 00001101”進行與運算後得到“00000000 00000000 00000000 00001101”,即“0.0.0.13”,這就是這個IP地址主機號(可簡化爲“13”)。
主機位中有3位被劃爲“網絡標識號”佔用,因網絡標識號應全爲“1”,所以主機號對應的字節段爲“11100000”。轉換成十進制後爲224,這就最終確定的子網掩碼。如果是C類網,則子網掩碼爲255.255.255.224;如果是B類網,則子網掩碼爲255.255.224.0;如果是A類網,則子網掩碼爲255.224.0.0。
實現方法一:
package com.nynu;
/**
* @author ChenYanwei
* @version 1.0
*/
public class TestIp {
public static boolean isInRange(String network, String mask) {
String[] networkips = network.split("\\.");
int ipAddr = (Integer.parseInt(networkips[0]) << 24)
| (Integer.parseInt(networkips[1]) << 16)
| (Integer.parseInt(networkips[2]) << 8)
| Integer.parseInt(networkips[3]);
int type = Integer.parseInt(mask.replaceAll(".*/", ""));
int mask1 = 0xFFFFFFFF << (32 - type);
String maskIp = mask.replaceAll("/.*", "");
String[] maskIps = maskIp.split("\\.");
int cidrIpAddr = (Integer.parseInt(maskIps[0]) << 24)
| (Integer.parseInt(maskIps[1]) << 16)
| (Integer.parseInt(maskIps[2]) << 8)
| Integer.parseInt(maskIps[3]);
return (ipAddr & mask1) == (cidrIpAddr & mask1);
}
public static void main(String[] args) {
System.out.println(isInRange("10.153.48.127", "10.153.48.0/26"));
System.out.println(isInRange("10.168.1.2", "10.168.0.224/23"));
System.out.println(isInRange("192.168.0.1", "192.168.0.0/24"));
System.out.println(isInRange("10.168.0.0", "10.168.0.0/32"));
}
}
結果:
false
true
true
true
實現方法二
package com.nynu;
/**
* @author ChenYanwei
* @version 1.1
*/
public class TestIp1 {
public static boolean ipIsInNet(String iparea, String ip) {
if (iparea == null)
throw new NullPointerException("IP段不能爲空!");
if (ip == null)
throw new NullPointerException("IP不能爲空!");
iparea = iparea.trim();
ip = ip.trim();
final String REGX_IP = "((25[0-5]|2[0-4]//d|1//d{2}|[1-9]//d|//d)//.){3}(25[0-5]|2[0-4]//d|1//d{2}|[1-9]//d|//d)";
final String REGX_IPB = REGX_IP + "//-" + REGX_IP;
if (!iparea.matches(REGX_IPB) || !ip.matches(REGX_IP))
return false;
int idx = iparea.indexOf('-');
String[] sips = iparea.substring(0, idx).split("//.");
String[] sipe = iparea.substring(idx + 1).split("//.");
String[] sipt = ip.split("//.");
long ips = 0L, ipe = 0L, ipt = 0L;
for (int i = 0; i < 4; ++i) {
ips = ips << 8 | Integer.parseInt(sips[i]);
ipe = ipe << 8 | Integer.parseInt(sipe[i]);
ipt = ipt << 8 | Integer.parseInt(sipt[i]);
}
if (ips > ipe) {
long t = ips;
ips = ipe;
ipe = t;
}
return ips <= ipt && ipt <= ipe;
}
public static void main(String[] args) {
System.out.println(ipIsInNet("10.153.48.127", "10.153.48.0/26"));
System.out.println(ipIsInNet("10.168.1.2", "10.168.0.224/23"));
System.out.println(ipIsInNet("192.168.0.1", "192.168.0.0/24"));
System.out.println(ipIsInNet("10.168.0.0", "10.168.0.0/32"));
}
}
結果:
false
false
false
false