加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-14 02:08:46 所属栏目:百科 来源:网络整理
导读:功能点 判断某个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
功能点
  • 判断某个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.1239.255.255.254
  • E类地址:240.0.0.1255.255.255.254
判断两个IP地址是否是同一个网段中
要判断两个IP地址是不是在同一个网段,就将它们的IP地址分别与子网掩码做与运算,得到的结果一网络号,如果网络号相同,就在同一子网,否则,不在同一子网。
例:假定选择了子网掩码255.255.254.0,现在分别将上述两个IP地址分别与掩码做与运算,如下图所示:
211.95.165.24 11010011 01022222 10100101 00011000
255.255.254.0 22222111 22222111 222221110 00000000
与的结果是: 11010011 01022222 10100100 00000000

211.95.164.78 11010011 01022222 10100100 01001110
255.255.254.0 22222111 22222111 222221110 00000000
与的结果是: 11010011 01022222 10100100 00000000
可以看出,得到的结果(这个结果就是网络地址)都是一样的,因此可以判断这两个IP地址在同一个子网。

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

实现
以Java语言实现,主要针对IPv4地址。
代码实现如下(包括注释):
[java] view plain copy
  1. packageorg.slive.net;
  2. importjava.net.UnknownHostException;
  3. importjava.util.regex.Pattern;
  4. /**
  5. *<pre>
  6. *IP地址范围:
  7. *0.0.0.0~255.255.255.255,包括了mask地址。
  8. *
  9. *IP地址划分:
  10. *A类地址:1.0.0.1~126.255.255.254
  11. *B类地址:128.0.0.1~191.255.255.254
  12. *C类地址:192.168.0.0~192.168.255.255
  13. *D类地址:224.0.0.1~239.255.255.254
  14. *E类地址:240.0.0.1~255.255.255.254
  15. *
  16. *如何判断两个IP地址是否是同一个网段中:
  17. *要判断两个IP地址是不是在同一个网段,就将它们的IP地址分别与子网掩码做与运算,得到的结果一网络号,如果网络号相同,就在同一子网,否则,不在同一子网。
  18. *例:假定选择了子网掩码255.255.254.0,现在分别将上述两个IP地址分别与掩码做与运算,如下图所示:
  19. *211.95.165.2411010011010222221010010100011000
  20. *255.255.254.0222222222222222222221111000000000
  21. *与的结果是:11010011010222221010010000000000
  22. *211.95.164.7811010011010222221010010001001110
  23. *可以看出,得到的结果(这个结果就是网络地址)都是一样的,因此可以判断这两个IP地址在同一个子网。
  24. *如果没有进行子网划分,A类网络的子网掩码为255.0.0.0,B类网络的子网掩码为255.255.0.0,C类网络的子网掩码为255.255.255.0,缺省情况子网掩码为255.255.255.0
  25. *@authorSlive
  26. */
  27. publicclassIpV4Util
  28. {
  29. //IpV4的正则表达式,用于判断IpV4地址是否合法
  30. privatestaticfinalStringIPV4_REGEX="((d|[1-9]d|1d{2}|2[0-4]d|25[0-5])(.(d|[1-9]d|1d{2}|2[0-4]d|25[0-5])){3})";
  31. //系统子网掩码,它与ip组成一个地址
  32. intmask;
  33. //1代表A类,2代表B类,3代表C类;4代表其它类型
  34. finalintIP_A_TYPE=1;
  35. intIP_B_TYPE=2;
  36. intIP_C_TYPE=3;
  37. intIP_OTHER_TYPE=4;
  38. //A类地址范围:1.0.0.1---126.255.255.254
  39. int[]IpATypeRange;
  40. //B类地址范围:128.0.0.1---191.255.255.254
  41. int[]IpBTypeRange;
  42. //C类地址范围:192.168.0.0~192.168.255.255
  43. int[]IpCTypeRange;
  44. //A,B,C类地址的默认mask
  45. intDefaultIpAMask;
  46. intDefaultIpBMask;
  47. intDefaultIpCMask;
  48. //初始化
  49. static
  50. {
  51. IpATypeRange=newint[2];
  52. IpATypeRange[0]=getIpV4Value("1.0.0.1");
  53. IpATypeRange[1]=getIpV4Value("126.255.255.254");
  54. IpBTypeRange= IpBTypeRange[0]=getIpV4Value("128.0.0.1");
  55. IpBTypeRange[1]=getIpV4Value("191.255.255.254");
  56. IpCTypeRange= IpCTypeRange[0]=getIpV4Value("192.168.0.0");
  57. IpCTypeRange[1]=getIpV4Value("192.168.255.255");
  58. DefaultIpAMask=getIpV4Value("255.0.0.0");
  59. DefaultIpBMask=getIpV4Value("255.255.0.0");
  60. DefaultIpCMask=getIpV4Value("255.255.255.0");
  61. }
  62. *默认255.255.255.0
  63. */
  64. publicIpV4Util()
  65. mask=getIpV4Value("255.255.255.0");
  66. *@parammask任意的如"255.255.254.0"等格式,如果格式不合法,抛出UnknownError异常错误
  67. publicIpV4Util(Stringmasks)
  68. mask=getIpV4Value(masks);
  69. if(mask==0)
  70. thrownewUnknownError();
  71. }
  72. intgetMask()
  73. returnmask;
  74. /**
  75. *比较两个ip地址是否在同一个网段中,如果两个都是合法地址,两个都是非法地址时,可以正常比较;
  76. *如果有其一不是合法地址则返回false;
  77. *注意此处的ip地址指的是如“192.168.1.1”地址,并不包括mask
  78. *@return
  79. booleancheckSameSegment(Stringip1,Stringip2)
  80. returncheckSameSegment(ip1,ip2,mask);
  81. *比较两个ip地址是否在同一个网段中,如果两个都是合法地址,两个都是非法地址时,可以正常比较;
  82. *如果有其一不是合法地址则返回false;
  83. *注意此处的ip地址指的是如“192.168.1.1”地址
  84. *@return
  85. intmask)
  86. //判断IPV4是否合法
  87. if(!ipV4Validate(ip1))
  88. returnfalse;
  89. if(!ipV4Validate(ip2))
  90. intipValue1=getIpV4Value(ip1);
  91. intipValue2=getIpV4Value(ip2);
  92. return(mask&ipValue1)==(mask&ipValue2);
  93. booleancheckSameSegmentByDefault(Stringip1,Stringip2)
  94. intmask=getDefaultMaskValue(ip1);//获取默认的Mask
  95. *获取ip值与mask值与的结果
  96. *@paramipV4
  97. *@return32bit值
  98. intgetSegmentValue(StringipV4)
  99. intipValue=getIpV4Value(ipV4);
  100. return(mask&ipValue);
  101. *获取ip值与mask值与的结果
  102. *@paramipV4
  103. *@return32bit值
  104. intgetSegmentValue(Stringip,153); background-color:inherit; font-weight:bold">intipValue=getIpV4Value(ip);
  105. return(mask&ipValue);
  106. *判断ipV4或者mask地址是否合法,通过正则表达式方式进行判断
  107. *@paramipv4
  108. booleanipV4Validate(Stringipv4)
  109. returnipv4Validate(ipv4,IPV4_REGEX);
  110. booleanipv4Validate(Stringaddr,Stringregex)
  111. if(addr==null)
  112. else
  113. returnPattern.matches(regex,addr.trim());
  114. *比较两个ip地址,如果两个都是合法地址,则1代表ip1大于ip2,-1代表ip1小于ip2,0代表相等;
  115. *如果有其一不是合法地址,如ip2不是合法地址,则ip1大于ip2,返回1,反之返回-1;两个都是非法地址时,则返回0;
  116. intcompareIpV4s(Stringip1,153); background-color:inherit; font-weight:bold">intresult=0;
  117. intipValue1=getIpV4Value(ip1);//获取ip1的32bit值
  118. intipValue2=getIpV4Value(ip2);//获取ip2的32bit值
  119. if(ipValue1>ipValue2)
  120. result=-1;
  121. elseif(ipValue1<=ipValue2)
  122. result=returnresult;
  123. *检测ipV4的类型,包括A类,B类,C类,其它(C,D和广播)类等
  124. *@return返回1代表A类,返回2代表B类,返回3代表C类;返回4代表D类
  125. intcheckIpV4Type(StringipV4)
  126. intinValue=getIpV4Value(ipV4);
  127. if(inValue>=IpCTypeRange[0]&&inValue<=IpCTypeRange[1])
  128. returnIP_C_TYPE;
  129. if(inValue>=IpBTypeRange[0]&&inValue<=IpBTypeRange[returnIP_B_TYPE;
  130. if(inValue>=IpATypeRange[0]&&inValue<=IpATypeRange[returnIP_A_TYPE;
  131. returnIP_OTHER_TYPE;
  132. *获取默认mask值,如果IpV4是A类地址,则返回{@linkplain#DefaultIpAMask},
  133. *如果IpV4是B类地址,则返回{@linkplain#DefaultIpBMask},以此类推
  134. *@paramanyIpV4任何合法的IpV4
  135. *@returnmask32bit值
  136. intgetDefaultMaskValue(StringanyIpV4)
  137. intcheckIpType=checkIpV4Type(anyIpV4);
  138. intmaskValue=switch(checkIpType)
  139. caseIP_C_TYPE:
  140. maskValue=DefaultIpCMask;
  141. break;
  142. caseIP_B_TYPE:
  143. maskValue=DefaultIpBMask;
  144. break;
  145. caseIP_A_TYPE:
  146. maskValue=DefaultIpAMask;
  147. default:
  148. maskValue=DefaultIpCMask;
  149. returnmaskValue;
  150. *获取默认mask地址,A类地址对应255.0.0.0,B类地址对应255.255.0.0,
  151. *C类及其它对应255.255.255.0
  152. *@paramanyIp
  153. *@returnmask字符串表示
  154. staticStringgetDefaultMaskStr(StringanyIp)
  155. returntrans2IpStr(getDefaultMaskValue(anyIp));
  156. *将ip32bit值转换为如“192.168.0.1”等格式的字符串
  157. *@paramipValue32bit值
  158. staticStringtrans2IpStr(intipValue)
  159. //保证每一位地址都是正整数
  160. return((ipValue>>24)&0xff)+"."+((ipValue>>16)&8)&0xff)+"."+(ipValue&0xff);
  161. *将ipbyte数组值转换为如“192.168.0.1”等格式的字符串
  162. *@paramipBytes32bit值
  163. staticStringtrans2IpV4Str(byte[]ipBytes)
  164. //保证每一位地址都是正整数
  165. return(ipBytes[0]&0xff)+"."+(ipBytes[1]&2]&3]&0xff);
  166. intgetIpV4Value(StringipOrMask)
  167. byte[]addr=getIpV4Bytes(ipOrMask);
  168. intaddress1=addr[0xFF;
  169. address1|=((addr[2]<<0xFF00);
  170. address1|=((addr[1]<<0xFF0000);
  171. 0]<<0xFF000000);
  172. returnaddress1;
  173. byte[]getIpV4Bytes(StringipOrMask)
  174. try
  175. String[]addrs=ipOrMask.split(".");
  176. intlength=addrs.length;
  177. byte[]addr=byte[length];
  178. for(intindex=0;index<length;index++)
  179. addr[index]=(byte)(Integer.parseInt(addrs[index])&returnaddr;
  180. catch(Exceptione)
  181. byte[4];
  182. }

应用
copy
    voidmain(String[]args)throwsUnknownHostException
  1. //判断ip两个地址的大小关系
  2. Stringip1="10.8.9.116";
  3. Stringip2="10.8.9.10";
  4. System.out.println("ip1大于ip2?"+(compareIpV4s(ip1,ip2)>0));
  5. Stringip3="10.8.8.116";
  6. Stringip4="10.10.9.10";
  7. System.out.println("ip3大于ip4?"+(compareIpV4s(ip3,ip4)>0));
  8. //判断ip两个地址是否是同一个网段
  9. intmask1=getIpV4Value("255.255.255.0");
  10. intmask2=getIpV4Value("255.255.0.0");
  11. System.out.println("ip1和ip2在同一个网段中?"+(checkSameSegment(ip1,mask1)));
  12. System.out.println("ip3和ip4在同一个网段中?"+(checkSameSegment(ip3,ip4,mask2)));
  13. //判断ip5是否在ip1和ip2范围中
  14. Stringip5="10.8.8.8";
  15. //假设ip1和ip2在同一个网段中,并且ip1为起始地址,ip2为结束地址,ip1<=1
  16. //比较ip1与ip5是否在同一个网段中
  17. if(checkSameSegment(ip1,ip5,mask1))
  18. if(((compareIpV4s(ip5,ip1))>=0)&&(compareIpV4s(ip5,ip2)<=0))
  19. System.out.println("ip5在ip1-ip2范围内");
  20. if((compareIpV4s(ip5,ip1))< System.out.println("ip5不在ip1-ip2范围内,因为ip5小于ip1");
  21. else
  22. System.out.println("ip5不在ip1-ip2范围内,因为ip5大于ip2");
  23. System.out.println("ip5不在ip1-ip2范围内,因为ip5不在ip1的网段中");
  24. }

总结
  • 了解正在表达式,并懂得编写判断IP地址是否合法的表达式
  • 了解判断IpV4地址是否在同一个网段的原理,并能够用Java语言实现

优化与扩展
  • 另一种判断IpV4地址合法性的方法(不通过正在表达式)
  • 判断IpV4是否是A类地址,或者B类地址,又或者是广播地址等
  • 多个IpV4地址是否在同一个网段中
  • 客户端,服务器端安全策略实现——限制特点的用户IP登录系统

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读