Java验证IP地址是否属于指定局域网网段

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_35770741/article/details/78310656

首先我们需要知道子网和子网掩码的作用

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的子网掩码。

现有子网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();
	}
得到结果为:
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;

startNetworkAddress = "11000000101010000000000000000000";
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;
	}

最后根据方法返回值得到IP地址是否在指定的网段内。

以上是前端时间写的一个简单的demo,如有需要了解详细的关于IP和子网掩码知识的小伙伴可以访问下面的链接, 点击打开链接 。

另外demo中有不足或不正确的地方欢迎指正,谢谢。


猜你喜欢

转载自blog.csdn.net/qq_35770741/article/details/78310656