功能点
  • 判断某个IP地址是否合法

  • 判断两个IP地址是否在同一个网段中

  • 判断两个IP地址的大小关系

知识准备
  • IP协议

  • 子网掩码

  • Java

  • 正则表达式

基本原理

IP地址范围
0.0.0.0~255.255.255.255,包括了mask地址。
IP地址划分
  • A类地址:1.0.0.1~126.255.255.254

  • B类地址:128.0.0.1~191.255.255.254

  • C类地址:192.168.0.0~192.168.255.255

  • D类地址:224.0.0.1~239.255.255.254

  • E类地址:240.0.0.1~255.255.255.254

判断两个IP地址是否是同一个网段中
要判断两个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地址在同一个子网。

如果没有进行子网划分,A类网络的子网掩码为255.0.0.0,B类网络的子网掩码为255.255.0.0,C类网络的子网掩码为255.255.255.0,缺省情况子网掩码为255.255.255.0

实现
  以Java语言实现,主要针对IPv4地址。

代码实现如下(包括注释):

package org.slive.net;
import java.net.UnknownHostException;
import java.util.regex.Pattern;
/**
* <pre>
* IP地址范围:
* 0.0.0.0~255.255.255.255,包括了mask地址。
*
* IP地址划分:
* A类地址:1.0.0.1~126.255.255.254
* B类地址:128.0.0.1~191.255.255.254
* C类地址:192.168.0.0~192.168.255.255
* D类地址:224.0.0.1~239.255.255.254
* E类地址:240.0.0.1~255.255.255.254
*
* 如何判断两个IP地址是否是同一个网段中:
* 要判断两个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地址在同一个子网。
*
* 如果没有进行子网划分,A类网络的子网掩码为255.0.0.0,B类网络的子网掩码为255.255.0.0,C类网络的子网掩码为255.255.255.0,缺省情况子网掩码为255.255.255.0
*
* @author Slive
*/
public class IpV4Util
{// IpV4的正则表达式,用于判断IpV4地址是否合法private static final String IPV4_REGEX = "((\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3})";// 系统子网掩码,它与ip组成一个地址private int mask;// 1代表A类,2代表B类,3代表C类;4代表其它类型public final static int IP_A_TYPE = 1;public final static int IP_B_TYPE = 2;public final static int IP_C_TYPE = 3;public final static int IP_OTHER_TYPE = 4;// A类地址范围:1.0.0.1---126.255.255.254private static int[] IpATypeRange;// B类地址范围:128.0.0.1---191.255.255.254private static int[] IpBTypeRange;// C类地址范围:192.168.0.0~192.168.255.255private static int[] IpCTypeRange;// A,B,C类地址的默认maskprivate static int DefaultIpAMask;private static int DefaultIpBMask;private static int DefaultIpCMask;// 初始化static{IpATypeRange = new int[2];IpATypeRange[0] = getIpV4Value("1.0.0.1");IpATypeRange[1] = getIpV4Value("126.255.255.254");IpBTypeRange = new int[2];IpBTypeRange[0] = getIpV4Value("128.0.0.1");IpBTypeRange[1] = getIpV4Value("191.255.255.254");IpCTypeRange = new int[2];IpCTypeRange[0] = getIpV4Value("192.168.0.0");IpCTypeRange[1] = getIpV4Value("192.168.255.255");DefaultIpAMask = getIpV4Value("255.0.0.0");DefaultIpBMask = getIpV4Value("255.255.0.0");DefaultIpCMask = getIpV4Value("255.255.255.0");}/*** 默认255.255.255.0*/public IpV4Util(){mask = getIpV4Value("255.255.255.0");}/*** @param mask 任意的如"255.255.254.0"等格式,如果格式不合法,抛出UnknownError异常错误*/public IpV4Util(String masks){mask = getIpV4Value(masks);if(mask == 0){throw new UnknownError();}}public int getMask(){return mask;}/*** 比较两个ip地址是否在同一个网段中,如果两个都是合法地址,两个都是非法地址时,可以正常比较;* 如果有其一不是合法地址则返回false;* 注意此处的ip地址指的是如“192.168.1.1”地址,并不包括mask* @return*/public boolean checkSameSegment(String ip1,String ip2){return checkSameSegment(ip1,ip2,mask);}/*** 比较两个ip地址是否在同一个网段中,如果两个都是合法地址,两个都是非法地址时,可以正常比较;* 如果有其一不是合法地址则返回false;* 注意此处的ip地址指的是如“192.168.1.1”地址* @return*/public static boolean checkSameSegment(String ip1,String ip2, int mask){// 判断IPV4是否合法if(!ipV4Validate(ip1)){return false;}if(!ipV4Validate(ip2)){return false;}int ipValue1 = getIpV4Value(ip1);int ipValue2 = getIpV4Value(ip2);return (mask & ipValue1) == (mask & ipValue2);}/*** 比较两个ip地址是否在同一个网段中,如果两个都是合法地址,两个都是非法地址时,可以正常比较;* 如果有其一不是合法地址则返回false;* 注意此处的ip地址指的是如“192.168.1.1”地址* @return*/public static boolean checkSameSegmentByDefault(String ip1,String ip2){int mask = getDefaultMaskValue(ip1);     // 获取默认的Maskreturn checkSameSegment(ip1,ip2,mask);}/*** 获取ip值与mask值与的结果* @param ipV4* @return  32bit值*/public int getSegmentValue(String ipV4){int ipValue = getIpV4Value(ipV4);return (mask & ipValue);}/*** 获取ip值与mask值与的结果* @param ipV4* @return  32bit值*/public static int getSegmentValue(String ip, int mask){int ipValue = getIpV4Value(ip);return (mask & ipValue);}/*** 判断ipV4或者mask地址是否合法,通过正则表达式方式进行判断* @param ipv4*/public static boolean ipV4Validate(String ipv4){return ipv4Validate(ipv4,IPV4_REGEX);}private static boolean ipv4Validate(String addr,String regex){if(addr == null){return false;}else{return Pattern.matches(regex, addr.trim());}}/*** 比较两个ip地址,如果两个都是合法地址,则1代表ip1大于ip2,-1代表ip1小于ip2,0代表相等;* 如果有其一不是合法地址,如ip2不是合法地址,则ip1大于ip2,返回1,反之返回-1;两个都是非法地址时,则返回0;* 注意此处的ip地址指的是如“192.168.1.1”地址,并不包括mask* @return*/public static int compareIpV4s(String ip1,String ip2){int result = 0;int ipValue1 = getIpV4Value(ip1);     // 获取ip1的32bit值int ipValue2 = getIpV4Value(ip2); // 获取ip2的32bit值if(ipValue1 > ipValue2){result =  -1;}else if(ipValue1 <= ipValue2){result = 1;}return result;}/*** 检测ipV4 的类型,包括A类,B类,C类,其它(C,D和广播)类等* @param ipV4* @return     返回1代表A类,返回2代表B类,返回3代表C类;返回4代表D类*/public static int checkIpV4Type(String ipV4){int inValue = getIpV4Value(ipV4);if(inValue >= IpCTypeRange[0] && inValue <= IpCTypeRange[1]){return IP_C_TYPE;}else if(inValue >= IpBTypeRange[0] && inValue <= IpBTypeRange[1]){return IP_B_TYPE;}else if(inValue >= IpATypeRange[0] && inValue <= IpATypeRange[1]){return IP_A_TYPE;}return IP_OTHER_TYPE;}/*** 获取默认mask值,如果IpV4是A类地址,则返回{@linkplain #DefaultIpAMask},* 如果IpV4是B类地址,则返回{@linkplain #DefaultIpBMask},以此类推* @param anyIpV4 任何合法的IpV4* @return mask 32bit值*/public static int getDefaultMaskValue(String anyIpV4){int checkIpType = checkIpV4Type(anyIpV4);int maskValue = 0;switch (checkIpType){case IP_C_TYPE:maskValue = DefaultIpCMask;break;case IP_B_TYPE:maskValue = DefaultIpBMask;break;case IP_A_TYPE:maskValue = DefaultIpAMask;break;default:maskValue = DefaultIpCMask;}return maskValue;}/*** 获取默认mask地址,A类地址对应255.0.0.0,B类地址对应255.255.0.0,* C类及其它对应255.255.255.0* @param anyIp* @return mask 字符串表示*/public static String getDefaultMaskStr(String anyIp){return trans2IpStr(getDefaultMaskValue(anyIp));}/*** 将ip 32bit值转换为如“192.168.0.1”等格式的字符串* @param ipValue 32bit值* @return*/public static String trans2IpStr(int ipValue){// 保证每一位地址都是正整数return ((ipValue >> 24) & 0xff) + "." + ((ipValue >> 16) & 0xff) + "." + ((ipValue >> 8) & 0xff) + "." + (ipValue & 0xff);}/*** 将ip byte数组值转换为如“192.168.0.1”等格式的字符串* @param ipBytes 32bit值* @return*/public static String trans2IpV4Str(byte[] ipBytes){// 保证每一位地址都是正整数return (ipBytes[0] & 0xff) + "." + (ipBytes[1] & 0xff) + "." + (ipBytes[2] & 0xff) + "." + (ipBytes[3] & 0xff);}public static int getIpV4Value(String ipOrMask){byte[] addr = getIpV4Bytes(ipOrMask);int address1  = addr[3] & 0xFF;address1 |= ((addr[2] << 8) & 0xFF00);address1 |= ((addr[1] << 16) & 0xFF0000);address1 |= ((addr[0] << 24) & 0xFF000000);return address1;}public static byte[] getIpV4Bytes(String ipOrMask){try{String[] addrs = ipOrMask.split("\\.");int length = addrs.length;byte[] addr = new byte[length];for (int index = 0; index < length; index++){addr[index] = (byte) (Integer.parseInt(addrs[index]) & 0xff);}return addr;}catch (Exception e){}return new byte[4];}
}

应用

public static void main(String[] args) throws UnknownHostException{// 判断ip两个地址的大小关系String ip1 = "10.8.9.116";String ip2 = "10.8.9.10";System. out.println("ip1 大于 ip2? " + (compareIpV4s (ip1, ip2) > 0));String ip3= "10.8.8.116";String ip4 = "10.10.9.10";System. out.println("ip3 大于 ip4? " + (compareIpV4s (ip3, ip4) > 0));// 判断ip两个地址是否是同一个网段int mask1 = getIpV4Value( "255.255.255.0");int mask2 = getIpV4Value( "255.255.0.0");System. out.println("ip1和ip2在同一个网段中? " + (checkSameSegment(ip1, ip2, mask1)));System. out.println("ip3和ip4在同一个网段中 ?" + (checkSameSegment(ip3, ip4, mask2)));// 判断ip5是否在ip1和ip2范围中String ip5= "10.8.8.8";// 假设ip1和ip2在同一个网段中,并且ip1为起始地址,ip2为结束地址,ip1<=1// 比较ip1与ip5是否在同一个网段中if(checkSameSegment(ip1, ip5, mask1)){// 判断ip5是否在ip1和ip2范围中if(((compareIpV4s(ip5, ip1)) >= 0) && (compareIpV4s(ip5, ip2) <= 0)){System. out.println("ip5 在ip1-ip2范围内" );}else if ((compareIpV4s(ip5, ip1)) < 0){System. out.println("ip5 不在ip1-ip2范围内,因为ip5小于ip1" );}else{System. out.println("ip5 不在ip1-ip2范围内,因为ip5大于ip2" );}}else{System. out.println("ip5 不在ip1-ip2范围内,因为ip5不在ip1的网段中" );}}
总结

  • 了解正在表达式,并懂得编写判断IP地址是否合法的表达式

  • 了解判断IpV4地址是否在同一个网段的原理,并能够用Java语言实现

优化与扩展
  • 另一种判断IpV4地址合法性的方法(不通过正在表达式)

  • 判断IpV4是否是A类地址,或者B类地址,又或者是广播地址等

  • 多个IpV4地址是否在同一个网段中

  • 客户端,服务器端安全策略实现——限制特点的用户IP登录系统

转载于:https://blog.51cto.com/slive/1286964

判断两个IP大小关系及是否在同一个网段中相关推荐

  1. 判断两个IP大小及是否在同一个网段中

    功能点  判断某个IP地址是否合法 判断两个IP地址是否在同一个网段中 判断两个IP地址的大小关系 知识准备 IP协议 子网掩码 Java 正则表达式 基本原理 IP地址范围 0.0.0.0- 255 ...

  2. linux数字大小判断,if 判断两个数值大小--多分支if语句实现对参数的严格判断

    if判断两个数值大小--多分支if语句实现对参数的严格判断 #!/bin/bash print_usage(){ printf"你输入的参数个数不对或者有误,请按照下面语法执行:\n&quo ...

  3. 一个路由器两个网段互通_如何判断两个IP地址是否在同一个网段?什么是子网掩码?...

    前几天咱们了解:三种方法告诉你项目超过255个摄像机怎么设置IP?什么是公网ip?什么又是内网ip?为什么ip地址通常以192.168开头? 也学习了:二.三层交换机与路由器的区别! 但是有好多人对I ...

  4. 如何判断两个IP地址是不是处于同一网段?

    个人理解,欢迎指正. 一.要判断两个IP地址是不是在同一个网段,就将它们的IP地址分别与子网掩码做与运算,得到的结果-->网络号,如果网络号相同, 就在同一子网,否则,不在同一子网. 例:假定选 ...

  5. qprocess start怎么判断是否结束_怎么样判断两个IP地址是否在同一个网段

    怎么样判断两个IP地址是否在同一个网段 方法 通过自身的IP与自身掩码算出网络地址X 通过目的IP与自身掩码算出目的地的网络地址Y 如果这两个网络一样(X=Y),则表示目的地与自身在一个网络内 如果两 ...

  6. 怎样判断两个ip地址是不是在同一个网段中?

    我们先来了解一下,判断两个ip地址是不是在同一个网段的方法. 要想判断两个ip地址是不是在同一个网段,只需将ip地址与子网掩码做与运算,如果得出的结果一样,则这两个ip地址是同一个子网当中. 例子: ...

  7. 如何判断两个ip是否属于同一子网;如何确定子网掩码,让300台服务器处于同一网段

    一.什么是子网掩码? 在了解ip地址的网段之前,我们先来了解子网掩码,很多对网络了解不深的朋友都对子网掩码有些迷惑, 不了解它是用来干什么的? 子网掩码不能单独存在,它必须结合IP地址一起使用.子网掩 ...

  8. 如何判断两个IP地址是不是同一个网段(超实用)

    IP地址 IP地址被用来给Internet上的电脑一个编号.大家日常见到的情况是每台联网的PC上都需要有IP地址,才能正常通信.我们可以把"个人电脑"比作"一台电话&qu ...

  9. 判断两个IP地址(ipv4)是否在同一个网段

    我们通常会遇到的ip地址是这样的: ip地址:192.168.227.205 子网掩码:255.255.255.0 ip地址:192.168.226.202 子网掩码:255.255.255.0 19 ...

最新文章

  1. 机器学习各领域必读经典综述
  2. outlook 单独安装_民强村排烟管道安装公司
  3. 大数据和云计算涉及的技术_云计算涉及的风险
  4. 安装eclipse及android,Eclipse Android 安装
  5. 在Blazor中构建数据库应用程序——第3部分——UI中的CRUD编辑和查看操作
  6. Element-UI安装和项目开发
  7. hdu1113 Word Amalgamation(详解--map和string的运用)
  8. CMOS工作原理和概念
  9. android 开发 耳机接口 自拍,首次用KXD手机就为之倾倒,这就是KXD K30手机带来了魅力...
  10. 有感而发谈谈苏轼的一生
  11. python判断火车票座位号分布图_如何选择火车靠窗座位和选座位技巧!
  12. html修改网站图标,分享内容,分享图标等
  13. 《戴尔·卡耐基传记》--[美]戴尔·卡耐基
  14. 基于Web SCADA平台的食品饮料行业数字化系统
  15. 清爽的VS开发字体 -- Consolas
  16. Linux下获取cpu温度
  17. 【tensorflow】制作自己的数据集
  18. 怎么快速了解一个新的项目
  19. STM32L031 HAL库读写内部EEprom
  20. 蒲月“登高”,临风眺望,旷视邀您共赴AI的下一个十年之约

热门文章

  1. 堪比“脏牛”!“脏管道” 漏洞可获得Linux 所有主流发行版本的root权限
  2. 谷歌紧急修复已遭在野利用的Chrome 0day
  3. 黑莓 QNX 被曝严重的 BadAlloc 漏洞 影响数百万汽车和医疗设备
  4. ERP 平台Sage X3被曝多个严重漏洞,系统可遭接管,存在潜在供应链风险
  5. 阿里云云中沙箱自助实验-从Gitlab数据库被删看数据备份的重要性!
  6. mysql启动报错解决-1
  7. en 2014-12-31
  8. Ant构建与部署Java项目---入门
  9. Vue 2.0 + Vue Router + Vuex 后台管理系统的骨架
  10. linux舵机控制程序,Linux PWM设备驱动及舵机控制