首先我们需要知道子网和子网掩码的作用
1、子网的主要作用就是为了减少IP的浪费
2、子网掩码的作用,通过IP地址的二进制与子网掩码的二进制进行与运算,来确定某个设备的网络地址和主机号。子网掩码设置了之后,可以固定主机地址和网络地址。我们经常看到的子网掩码255.255.255.0,是由二进制数转换来的并通过二进制数进行计算。
利用子网数来计算子网掩码
首先要清楚划分的子网数目,以及每个子网内所需要的主机数目。
1)、将子网数目转化为二进制来表示
2)、取得该二进制的位数,为N
3)、取得该IP地址的类子网掩码,将其主机地址部分的前N位置1即得出该IP地址划分的子网掩码。
如将B类IP地址168.195.0.0划分为27个子网
27转化二进制数为11011
该二进制为五位数,N=5
将B类地址的子网掩码255.255.0.0的主机地址前5位置1,得到255.255.248.0,即为划分成27个子网的B类地址168.195.0.0的子网掩码
利用主机数来计算
1)、将主机地数目转化为二进制来表示
2)、如果主机数小于或等于254(注意去掉保留的两个IP地址),则取得该主机的二进制位数,为 N,这里肯定N<8。如果大于254,则 N>8,这就是说主机地址将占据不止8位。
3)、使用255.255.255.255来将该类IP地址的主机地址位数全部置1,然后从后向前的将N位全部置为 0,即为子网掩码值。
如将B类IP地址168.195.0.0划分成若干子网,每个子网内有主机700台:
700=1010111100
该二进制为十位数,N = 10
将该B类地址的子网掩码255.255.0.0的主机地址全部置1,得到255.255.255.255 然后再从后向前将后10位置0,即为: 11111111.11111111.11111100.00000000
即255.255.252.0。这就是划分成主机为700台的B类IP地址168.195.0.0的子网掩码。
将该B类地址的子网掩码255.255.0.0的主机地址全部置1,得到255.255.255.255 然后再从后向前将后10位置0,即为: 11111111.11111111.11111100.00000000
即255.255.252.0。这就是划分成主机为700台的B类IP地址168.195.0.0的子网掩码。
现有子网IP地址192.168.0.1 ,子网掩码255.255.255.0,需要验证10.10.1.15是否属于同一局域网网段。
首先通过此方法分别获取子网ip地址和子网掩码的二进制数。
public String getBinaryNumber(String address){
String[] networkAddressArray = address.split("\\.");
StringBuffer sb = new StringBuffer();
for (int i = 0; i < networkAddressArray.length; i++) {
String str = networkAddressArray[i];
if(Integer.toBinaryString(Integer.parseInt(str)).length()<8){
int num = 8-Integer.toBinaryString(Integer.parseInt(str)).length();
String ipStr1 = "";
for (int j = 0; j < num; j++) {
ipStr1 += "0";
}
sb.append(ipStr1+(String)Integer.toBinaryString(Integer.parseInt(str)));
}else{
sb.append((String)Integer.toBinaryString(Integer.parseInt(str)));
}
}
return sb.toString();
}
public String getBinaryNumber(String address){
String[] networkAddressArray = address.split("\\.");
StringBuffer sb = new StringBuffer();
for (int i = 0; i < networkAddressArray.length; i++) {
String str = networkAddressArray[i];
if(Integer.toBinaryString(Integer.parseInt(str)).length()<8){
int num = 8-Integer.toBinaryString(Integer.parseInt(str)).length();
String ipStr1 = "";
for (int j = 0; j < num; j++) {
ipStr1 += "0";
}
sb.append(ipStr1+(String)Integer.toBinaryString(Integer.parseInt(str)));
}else{
sb.append((String)Integer.toBinaryString(Integer.parseInt(str)));
}
}
return sb.toString();
}
得到结果为:
String networkAddress = "11000000101010000000000000000001";
String subnetMask = "11111111111111111111111100000000";
接下来要得到子网掩码设置的IP范围:
计算方式:
String zero = "" , one = "" ;
int i = 1;
//i为掩码二进制数中1的长度+1
for (;i <= subnetMask.length(); i++) {
String str =subnetMask.substring(i-1,i);
if(str.equals("0")){
break;
}
}
for (int j = 0; j < 32-i; j++) {
zero = zero + "0";
one = one + "1";
}
//将子网ip地址的二进制码进行截取拼接
String startNetworkAddress = networkAddress.substring(0,i) + zero;
String endNetworkAddress = networkAddress.substring(0,i) + one;
String zero = "" , one = "" ;
int i = 1;
//i为掩码二进制数中1的长度+1
for (;i <= subnetMask.length(); i++) {
String str =subnetMask.substring(i-1,i);
if(str.equals("0")){
break;
}
}
for (int j = 0; j < 32-i; j++) {
zero = zero + "0";
one = one + "1";
}
//将子网ip地址的二进制码进行截取拼接
String startNetworkAddress = networkAddress.substring(0,i) + zero;
String endNetworkAddress = networkAddress.substring(0,i) + one;
endNetworkAddress = "11000000101010000000000001111111";
将二进制数转化为IP地址
public String getDecimalismByBinary(String address){
String str = "";
for (int i = 1; i <= 4; i++) {
str += Integer.parseInt(address.substring((i-1)*8,i*8),2)+".";
}
return str.substring(0,str.length()-1);
}
现在将组装好的参数传入到方法中进行比较。
192.168.0.0-192.168.0.127,10.10.1.15
/**
*
* @param ipSection 有效ip范围,如192.168.0.0-192.168.0.127
* @param ip 需要验证的IP地址
* @return
*/
public static boolean ipIsValid(String ipSection, String ip) {
if (ipSection == null)
throw new NullPointerException("IP段不能为空!");
if (ip == null)
throw new NullPointerException("IP不能为空!");
ipSection = ipSection.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 (!ipSection.matches(REGX_IPB) || !ip.matches(REGX_IP))
return false;
int idx = ipSection.indexOf('-');
String[] sips = ipSection.substring(0, idx).split("\\.");
String[] sipe = ipSection.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;
}
/**
*
* @param ipSection 有效ip范围,如192.168.0.0-192.168.0.127
* @param ip 需要验证的IP地址
* @return
*/
public static boolean ipIsValid(String ipSection, String ip) {
if (ipSection == null)
throw new NullPointerException("IP段不能为空!");
if (ip == null)
throw new NullPointerException("IP不能为空!");
ipSection = ipSection.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 (!ipSection.matches(REGX_IPB) || !ip.matches(REGX_IP))
return false;
int idx = ipSection.indexOf('-');
String[] sips = ipSection.substring(0, idx).split("\\.");
String[] sipe = ipSection.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;
}
最后根据方法返回值得到IP地址是否在指定的网段内。
如果文章的内容对你有帮助,欢迎关注公众号:优享JAVA(ID:YouXiangJAVA),那里有更多的技术干货,并精心准备了一份程序员书单。期待你的到来!