功能点
- 判断某个IP地址是否合法
- 判断两个IP地址是否在同一个网段中
- 判断两个IP地址的大小关系
知识准备
基本原理
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 00011000255.255.254.0 11111111 11111111 111111110 00000000与的结果是: 11010011 01011111 10100100 00000000
211.95.164.78 11010011 01011111 10100100 01001110255.255.254.0 11111111 11111111 111111110 00000000与的结果是: 11010011 01011111 10100100 00000000
可以看出,得到的结果(这个结果就是网络地址)都是一样的,因此可以判断这两个IP地址在同一个子网。
实现
以Java语言实现,主要针对IPv4地址。
- packageorg.slive.net;
- importjava.net.UnknownHostException;
- importjava.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.2411010011010111111010010100011000
- *255.255.254.0111111111111111111111111000000000
- *与的结果是:11010011010111111010010000000000
- *211.95.164.7811010011010111111010010001001110
- *可以看出,得到的结果(这个结果就是网络地址)都是一样的,因此可以判断这两个IP地址在同一个子网。
- *如果没有进行子网划分,A类网络的子网掩码为255.0.0.0,B类网络的子网掩码为255.255.0.0,C类网络的子网掩码为255.255.255.0,缺省情况子网掩码为255.255.255.0
- *@authorSlive
- */
- publicclassIpV4Util
- {
- //IpV4的正则表达式,用于判断IpV4地址是否合法
- privatestaticfinalStringIPV4_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组成一个地址
- intmask;
- //1代表A类,2代表B类,3代表C类;4代表其它类型
- finalintIP_A_TYPE=1;
- intIP_B_TYPE=2;
- intIP_C_TYPE=3;
- intIP_OTHER_TYPE=4;
- //A类地址范围:1.0.0.1---126.255.255.254
- int[]IpATypeRange;
- //B类地址范围:128.0.0.1---191.255.255.254
- int[]IpBTypeRange;
- //C类地址范围:192.168.0.0~192.168.255.255
- int[]IpCTypeRange;
- //A,B,C类地址的默认mask
- intDefaultIpAMask;
- intDefaultIpBMask;
- intDefaultIpCMask;
- //初始化
- static
- {
- IpATypeRange=newint[2];
- IpATypeRange[0]=getIpV4Value("1.0.0.1");
- IpATypeRange[1]=getIpV4Value("126.255.255.254");
- IpBTypeRange= IpBTypeRange[0]=getIpV4Value("128.0.0.1");
- IpBTypeRange[1]=getIpV4Value("191.255.255.254");
- IpCTypeRange= 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
- */
- publicIpV4Util()
- mask=getIpV4Value("255.255.255.0");
- *@parammask任意的如"255.255.254.0"等格式,如果格式不合法,抛出UnknownError异常错误
- publicIpV4Util(Stringmasks)
- mask=getIpV4Value(masks);
- if(mask==0)
- thrownewUnknownError();
- }
- intgetMask()
- returnmask;
- /**
- *比较两个ip地址是否在同一个网段中,如果两个都是合法地址,两个都是非法地址时,可以正常比较;
- *如果有其一不是合法地址则返回false;
- *注意此处的ip地址指的是如“192.168.1.1”地址,并不包括mask
- *@return
- booleancheckSameSegment(Stringip1,Stringip2)
- returncheckSameSegment(ip1,ip2,mask);
- *比较两个ip地址是否在同一个网段中,如果两个都是合法地址,两个都是非法地址时,可以正常比较;
- *如果有其一不是合法地址则返回false;
- *注意此处的ip地址指的是如“192.168.1.1”地址
- *@return
- intmask)
- //判断IPV4是否合法
- if(!ipV4Validate(ip1))
- returnfalse;
- if(!ipV4Validate(ip2))
- intipValue1=getIpV4Value(ip1);
- intipValue2=getIpV4Value(ip2);
- return(mask&ipValue1)==(mask&ipValue2);
- booleancheckSameSegmentByDefault(Stringip1,Stringip2)
- intmask=getDefaultMaskValue(ip1);//获取默认的Mask
- *获取ip值与mask值与的结果
- *@paramipV4
- *@return32bit值
- intgetSegmentValue(StringipV4)
- intipValue=getIpV4Value(ipV4);
- return(mask&ipValue);
- *获取ip值与mask值与的结果
- *@paramipV4
- *@return32bit值
- intgetSegmentValue(Stringip,153); background-color:inherit; font-weight:bold">intipValue=getIpV4Value(ip);
- return(mask&ipValue);
- *判断ipV4或者mask地址是否合法,通过正则表达式方式进行判断
- *@paramipv4
- booleanipV4Validate(Stringipv4)
- returnipv4Validate(ipv4,IPV4_REGEX);
- booleanipv4Validate(Stringaddr,Stringregex)
- if(addr==null)
- else
- returnPattern.matches(regex,addr.trim());
- *比较两个ip地址,如果两个都是合法地址,则1代表ip1大于ip2,-1代表ip1小于ip2,0代表相等;
- *如果有其一不是合法地址,如ip2不是合法地址,则ip1大于ip2,返回1,反之返回-1;两个都是非法地址时,则返回0;
- intcompareIpV4s(Stringip1,153); background-color:inherit; font-weight:bold">intresult=0;
- intipValue1=getIpV4Value(ip1);//获取ip1的32bit值
- intipValue2=getIpV4Value(ip2);//获取ip2的32bit值
- if(ipValue1>ipValue2)
- result=-1;
- elseif(ipValue1<=ipValue2)
- result=returnresult;
- *检测ipV4的类型,包括A类,B类,C类,其它(C,D和广播)类等
- *@return返回1代表A类,返回2代表B类,返回3代表C类;返回4代表D类
- intcheckIpV4Type(StringipV4)
- intinValue=getIpV4Value(ipV4);
- if(inValue>=IpCTypeRange[0]&&inValue<=IpCTypeRange[1])
- returnIP_C_TYPE;
- if(inValue>=IpBTypeRange[0]&&inValue<=IpBTypeRange[returnIP_B_TYPE;
- if(inValue>=IpATypeRange[0]&&inValue<=IpATypeRange[returnIP_A_TYPE;
- returnIP_OTHER_TYPE;
- *获取默认mask值,如果IpV4是A类地址,则返回{@linkplain#DefaultIpAMask},
- *如果IpV4是B类地址,则返回{@linkplain#DefaultIpBMask},以此类推
- *@paramanyIpV4任何合法的IpV4
- *@returnmask32bit值
- intgetDefaultMaskValue(StringanyIpV4)
- intcheckIpType=checkIpV4Type(anyIpV4);
- intmaskValue=switch(checkIpType)
- caseIP_C_TYPE:
- maskValue=DefaultIpCMask;
- break;
- caseIP_B_TYPE:
- maskValue=DefaultIpBMask;
- break;
- caseIP_A_TYPE:
- maskValue=DefaultIpAMask;
- default:
- maskValue=DefaultIpCMask;
- returnmaskValue;
- *获取默认mask地址,A类地址对应255.0.0.0,B类地址对应255.255.0.0,
- *C类及其它对应255.255.255.0
- *@paramanyIp
- *@returnmask字符串表示
- staticStringgetDefaultMaskStr(StringanyIp)
- returntrans2IpStr(getDefaultMaskValue(anyIp));
- *将ip32bit值转换为如“192.168.0.1”等格式的字符串
- *@paramipValue32bit值
- staticStringtrans2IpStr(intipValue)
- //保证每一位地址都是正整数
- return((ipValue>>24)&0xff)+"."+((ipValue>>16)&8)&0xff)+"."+(ipValue&0xff);
- *将ipbyte数组值转换为如“192.168.0.1”等格式的字符串
- *@paramipBytes32bit值
- staticStringtrans2IpV4Str(byte[]ipBytes)
- //保证每一位地址都是正整数
- return(ipBytes[0]&0xff)+"."+(ipBytes[1]&2]&3]&0xff);
- intgetIpV4Value(StringipOrMask)
- byte[]addr=getIpV4Bytes(ipOrMask);
- intaddress1=addr[0xFF;
- address1|=((addr[2]<<0xFF00);
- address1|=((addr[1]<<0xFF0000);
- 0]<<0xFF000000);
- returnaddress1;
- byte[]getIpV4Bytes(StringipOrMask)
- try
- String[]addrs=ipOrMask.split("\\.");
- intlength=addrs.length;
- byte[]addr=byte[length];
- for(intindex=0;index<length;index++)
- addr[index]=(byte)(Integer.parseInt(addrs[index])&returnaddr;
- catch(Exceptione)
- byte[4];
- }
应用