validationIP地址(带掩码)

我有ip地址和一个掩码,如10.1.1.1/32 。 我想检查10.1.1.1是否在该范围内。 是否有可以执行此操作的库或实用程序,或者我是否需要自己编写内容?

首先,您需要将IP地址转换为flat int ,这将更容易使用:

 String s = "10.1.1.99"; Inet4Address a = (Inet4Address) InetAddress.getByName(s); byte[] b = a.getAddress(); int i = ((b[0] & 0xFF) << 24) | ((b[1] & 0xFF) << 16) | ((b[2] & 0xFF) << 8) | ((b[3] & 0xFF) << 0); 

一旦你的IP地址为普通的int你可以做一些比特算术来执行检查:

 int subnet = 0x0A010100; // 10.1.1.0/24 int bits = 24; int ip = 0x0A010199; // 10.1.1.99 // Create bitmask to clear out irrelevant bits. For 10.1.1.0/24 this is // 0xFFFFFF00 -- the first 24 bits are 1's, the last 8 are 0's. // // -1 == 0xFFFFFFFF // 32 - bits == 8 // -1 << 8 == 0xFFFFFF00 mask = -1 << (32 - bits) if ((subnet & mask) == (ip & mask)) { // IP address is in the subnet. } 
 public static boolean netMatch(String addr, String addr1){ //addr is subnet address and addr1 is ip address. Function will return true, if addr1 is within addr(subnet) String[] parts = addr.split("/"); String ip = parts[0]; int prefix; if (parts.length < 2) { prefix = 0; } else { prefix = Integer.parseInt(parts[1]); } Inet4Address a =null; Inet4Address a1 =null; try { a = (Inet4Address) InetAddress.getByName(ip); a1 = (Inet4Address) InetAddress.getByName(addr1); } catch (UnknownHostException e){} byte[] b = a.getAddress(); int ipInt = ((b[0] & 0xFF) << 24) | ((b[1] & 0xFF) << 16) | ((b[2] & 0xFF) << 8) | ((b[3] & 0xFF) << 0); byte[] b1 = a1.getAddress(); int ipInt1 = ((b1[0] & 0xFF) << 24) | ((b1[1] & 0xFF) << 16) | ((b1[2] & 0xFF) << 8) | ((b1[3] & 0xFF) << 0); int mask = ~((1 << (32 - prefix)) - 1); if ((ipInt & mask) == (ipInt1 & mask)) { return true; } else { return false; } } 

这是一个以几种常见方式(包括IPv6)获取子网描述的版本。

基于此处发布的其他代码。 在IPv4地址上,它可能比在裸int上执行二进制操作的方法更慢。

 package de.c3oe.tryanderror; import java.math.BigInteger; import java.net.InetAddress; import java.net.UnknownHostException; /** * @author c3oe.de, based on snippets from Scott Plante, John Kugelmann */ public class Subnet { final private int bytesSubnetCount; final private BigInteger bigMask; final private BigInteger bigSubnetMasked; /** For use via format "192.168.0.0/24" or "2001:db8:85a3:880:0:0:0:0/57" */ public Subnet( final InetAddress subnetAddress, final int bits ) { this.bytesSubnetCount = subnetAddress.getAddress().length; // 4 or 16 this.bigMask = BigInteger.valueOf( -1 ).shiftLeft( this.bytesSubnetCount*8 - bits ); // mask = -1 << 32 - bits this.bigSubnetMasked = new BigInteger( subnetAddress.getAddress() ).and( this.bigMask ); } /** For use via format "192.168.0.0/255.255.255.0" or single address */ public Subnet( final InetAddress subnetAddress, final InetAddress mask ) { this.bytesSubnetCount = subnetAddress.getAddress().length; this.bigMask = null == mask ? BigInteger.valueOf( -1 ) : new BigInteger( mask.getAddress() ); // no mask given case is handled here. this.bigSubnetMasked = new BigInteger( subnetAddress.getAddress() ).and( this.bigMask ); } /** * Subnet factory method. * @param subnetMask format: "192.168.0.0/24" or "192.168.0.0/255.255.255.0" * or single address or "2001:db8:85a3:880:0:0:0:0/57" * @return a new instance * @throws UnknownHostException thrown if unsupported subnet mask. */ public static Subnet createInstance( final String subnetMask ) throws UnknownHostException { final String[] stringArr = subnetMask.split("/"); if ( 2 > stringArr.length ) return new Subnet( InetAddress.getByName( stringArr[ 0 ] ), (InetAddress)null ); else if ( stringArr[ 1 ].contains(".") || stringArr[ 1 ].contains(":") ) return new Subnet( InetAddress.getByName( stringArr[ 0 ] ), InetAddress.getByName( stringArr[ 1 ] ) ); else return new Subnet( InetAddress.getByName( stringArr[ 0 ] ), Integer.parseInt( stringArr[ 1 ] ) ); } public boolean isInNet( final InetAddress address ) { final byte[] bytesAddress = address.getAddress(); if ( this.bytesSubnetCount != bytesAddress.length ) return false; final BigInteger bigAddress = new BigInteger( bytesAddress ); return bigAddress.and( this.bigMask ).equals( this.bigSubnetMasked ); } @Override final public boolean equals( Object obj ) { if ( ! (obj instanceof Subnet) ) return false; final Subnet other = (Subnet)obj; return this.bigSubnetMasked.equals( other.bigSubnetMasked ) && this.bigMask.equals( other.bigMask ) && this.bytesSubnetCount == other.bytesSubnetCount; } @Override final public int hashCode() { return this.bytesSubnetCount; } @Override public String toString() { final StringBuilder buf = new StringBuilder(); bigInteger2IpString( buf, this.bigSubnetMasked, this.bytesSubnetCount ); buf.append( '/' ); bigInteger2IpString( buf, this.bigMask, this.bytesSubnetCount ); return buf.toString(); } static private void bigInteger2IpString( final StringBuilder buf, final BigInteger bigInteger, final int displayBytes ) { final boolean isIPv4 = 4 == displayBytes; byte[] bytes = bigInteger.toByteArray(); int diffLen = displayBytes - bytes.length; final byte fillByte = 0 > (int)bytes[ 0 ] ? (byte)0xFF : (byte)0x00; int integer; for ( int i = 0; i < displayBytes; i++ ) { if ( 0 < i && ! isIPv4 && i % 2 == 0 ) buf.append( ':' ); else if ( 0 < i && isIPv4 ) buf.append( '.' ); integer = 0xFF & (i < diffLen ? fillByte : bytes[ i - diffLen ]); if ( ! isIPv4 && 0x10 > integer ) buf.append( '0' ); buf.append( isIPv4 ? integer : Integer.toHexString( integer ) ); } } } 

感谢John Kugelman – 我使用他的代码片段来创建这个类。

 package bs; import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; /** * Represents an IP range based on an address/mask. * @author Scott Plante, using code snippets by John Kugelman. */ public class IPMask { public static void main(String args[]) throws UnknownHostException { IPMask ipmask; ipmask = IPMask.getIPMask("192.168.20.32/24"); System.out.println("Checking "+ipmask+"..."); test(ipmask, "192.168.20.31 ", true); test(ipmask, "192.168.20.32 ", true); test(ipmask, "192.168.20.33 ", true); test(ipmask, "192.168.20.34 ", true); test(ipmask, "192.168.20.35 ", true); test(ipmask, "192.168.20.36 ", true); test(ipmask, "192.168.20.254", true); test(ipmask, "192.168.20.157", true); test(ipmask, "192.168.21.1 ", false); test(ipmask, "192.168.19.255", false); test(ipmask, "192.168.24.1 ", false); ipmask = IPMask.getIPMask("192.168.20.32/31"); System.out.println("Checking "+ipmask+"..."); test(ipmask, "192.168.20.31 ", false); test(ipmask, "192.168.20.32 ", true); test(ipmask, "192.168.20.33 ", true); test(ipmask, "192.168.20.34 ", false); test(ipmask, "192.168.20.35 ", false); test(ipmask, "192.168.20.36 ", false); test(ipmask, "192.168.20.254", false); test(ipmask, "192.168.20.157", false); test(ipmask, "192.168.21.1 ", false); test(ipmask, "192.168.19.255", false); test(ipmask, "192.168.24.1 ", false); ipmask = IPMask.getIPMask("192.168.20.32/23"); System.out.println("Checking "+ipmask+"..."); test(ipmask, "192.168.20.31 ", true); test(ipmask, "192.168.20.32 ", true); test(ipmask, "192.168.20.33 ", true); test(ipmask, "192.168.20.254", true); test(ipmask, "192.168.21.254", true); test(ipmask, "192.168.19.255", false); test(ipmask, "192.168.24.1 ", false); } public static void test(IPMask ipmask, String addr, boolean expect) throws UnknownHostException { boolean got = ipmask.matches(addr); System.out.println(addr + "\t(" + expect + ") ?\t"+got + "\t" + (got==expect?"":"!!!!!!!!")); } private Inet4Address i4addr; private byte maskCtr; private int addrInt; private int maskInt; public IPMask(Inet4Address i4addr, byte mask) { this.i4addr = i4addr; this.maskCtr = mask; this.addrInt = addrToInt(i4addr); this.maskInt = ~((1 << (32 - maskCtr)) - 1); } /** IPMask factory method. * * @param addrSlashMask IP/Mask String in format "nnn.nnn.nnn.nnn/mask". If * the "/mask" is omitted, "/32" (just the single address) is assumed. * @return a new IPMask * @throws UnknownHostException if address part cannot be parsed by * InetAddress */ public static IPMask getIPMask(String addrSlashMask) throws UnknownHostException { int pos = addrSlashMask.indexOf('/'); String addr; byte maskCtr; if (pos==-1) { addr = addrSlashMask; maskCtr = 32; } else { addr = addrSlashMask.substring(0, pos); maskCtr = Byte.parseByte(addrSlashMask.substring(pos + 1)); } return new IPMask((Inet4Address) InetAddress.getByName(addr), maskCtr); } /** Test given IPv4 address against this IPMask object. * * @param testAddr address to check. * @return true if address is in the IP Mask range, false if not. */ public boolean matches(Inet4Address testAddr) { int testAddrInt = addrToInt(testAddr); return ((addrInt & maskInt) == (testAddrInt & maskInt)); } /** Convenience method that converts String host to IPv4 address. * * @param addr IP address to match in nnn.nnn.nnn.nnn format or hostname. * @return true if address is in the IP Mask range, false if not. * @throws UnknownHostException if the string cannot be decoded. */ public boolean matches(String addr) throws UnknownHostException { return matches((Inet4Address)InetAddress.getByName(addr)); } /** Converts IPv4 address to integer representation. */ private static int addrToInt(Inet4Address i4addr) { byte[] ba = i4addr.getAddress(); return (ba[0] << 24) | ((ba[1]&0xFF) << 16) | ((ba[2]&0xFF) << 8) | (ba[3]&0xFF); } @Override public String toString() { return "IPMask(" + i4addr.getHostAddress() + "/" + maskCtr + ")"; } @Override public boolean equals(Object obj) { if (obj == null) return false; if (getClass() != obj.getClass()) return false; final IPMask that = (IPMask) obj; return (this.addrInt == that.addrInt && this.maskInt == that.maskInt); } @Override public int hashCode() { return this.maskInt + this.addrInt; } } 

我必须在他的代码中为int转换添加一个掩码:

 Inet4Address a = (Inet4Address) InetAddress.getByName("192.192.192.192"); byte[] b = a.getAddress(); int i = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3] << 0); System.out.println(Integer.toHexString(i)); System.out.println(Integer.toHexString(addrToInt(a))); 

制作:

 ffffffc0 c0c0c0c0 

在我的系统上:

 $> uname -a Linux guin 2.6.37.6-0.5-desktop #1 SMP PREEMPT 2011-04-25 21:48:33 +0200 x86_64 x86_64 x86_64 GNU/Linux $> java -version java version "1.6.0_25" Java(TM) SE Runtime Environment (build 1.6.0_25-b06) Java HotSpot(TM) 64-Bit Server VM (build 20.0-b11, mixed mode) $> 

您可以从上面的类中删除main和test方法。 它们是从unit testing代码改编而来,为简单起见而添加到此处。