我有IP地址和掩碼,例如10.1.1.1/32
。我想檢查10.1.1.1
是否在該範圍內。是否有一個庫或實用程序會這樣做,或者我需要自己寫一些東西?驗證IP地址(帶掩碼)
回答
首先你要你的IP地址轉換爲平板int
s,這將是比較容易的工作:
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.
}
假設我以'String ip =「10.1.1.1」開始; int mask = 24'我如何獲得'0x0A010100'? – 2010-11-18 15:41:41
@ nn4l謝謝,更新了我的答案,包括您的更正。 – 2012-02-27 21:08:32
因此,在基類庫或某些推薦的第三方網絡掩碼處理軟件包中確實沒有對此提供支持? – binki 2015-04-02 04:22:31
感謝約翰庫格爾曼 - 我用他的代碼片段來創建這個類。
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)
$>
你可以從上面的c中刪除主要和測試方法姑娘。它們根據單元測試代碼進行了修改,並且爲了簡化而添加到此處
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));
}
}
}
- 1. 驗證IP地址/網絡掩碼
- 2. 驗證碼和IP地址
- 3. java掩碼ip地址
- 4. IP地址驗證與一個掩碼選擇輸入
- 5. IP地址驗證
- 6. 使用TextInput的IP地址掩碼
- 7. IP地址的掩碼文本框
- 8. 驗證IP地址 - python
- 9. IP地址驗證幫助
- 10. PHP驗證IP地址
- 11. 彈簧IP地址驗證
- 12. 帶子網掩碼的IP地址範圍
- 13. 在文件中查找帶子網掩碼的IP地址
- 14. 反轉掩碼IP地址(通配符掩碼)
- 15. 瞭解爲什麼某些IP地址沒有掩碼地址
- 16. 使用現有IP地址範圍驗證IP地址
- 17. 使用jQuery手機驗證ip地址
- 18. IP地址驗證不起作用
- 19. Rails設計驗證IP地址
- 20. Rails 3驗證URL或IP地址
- 21. 驗證和搜索IP地址
- 22. 使用bash腳本驗證IP地址
- 23. 驗證使用tcl的ip地址
- 24. 適當點的IP地址驗證在
- 25. 訪問計數和IP地址驗證
- 26. 嘗試使用javascript驗證IP地址
- 27. 驗證特殊形式的IP地址
- 28. 如何在C#中驗證IP地址
- 29. 驗證datastage中的IP地址
- 30. codeigniter中的ip地址數組驗證
的可能重複[有誰知道一個Java組件來檢查,如果IP地址是從特定的網絡/網絡掩碼?(http://stackoverflow.com/questions/577363/does-anyone-know-a- java-component-to-check-if-ip-address-is-from-particular-netwo) – 2010-11-18 00:37:15