2009-02-23 6 views

Trả lời

19

Jakarta Commons Netorg.apache.commons.net.util.SubnetUtils dường như đáp ứng nhu cầu của bạn. Dường như bạn làm điều gì đó như thế này:

SubnetInfo subnet = (new SubnetUtils("10.10.10.0", "255.255.255.128")).getInfo(); 
boolean test = subnet.isInRange("10.10.10.10"); 

Note, như carson chỉ ra, rằng Jakarta Commons Net có a bug có thể ngăn chặn nó từ đưa ra các câu trả lời đúng trong một số trường hợp. Carson đề xuất sử dụng phiên bản SVN để tránh lỗi này.

+4

Hãy cẩn thận khi sử dụng tính năng này. Có một lỗi sẽ giữ cho nó hoạt động không chính xác. Bạn có thể muốn kéo nó ra khỏi SVN. http://mail-archives.apache.org/mod_mbox/commons-issues/200902.mbox/%[email protected]%3E – carson

+0

@carson: Cảm ơn bạn đã cảnh báo. Tôi đã chỉnh sửa câu trả lời của mình để bao gồm thông tin này. – Eddie

9

Bạn cũng có thể thử

boolean inSubnet = (ip & netmask) == (subnet & netmask); 

hoặc ngắn hơn

boolean inSubnet = (ip^subnet) & netmask == 0; 
+0

IP và netmask có phải là ints hoặc longs không? – simgineer

+0

Địa chỉ 32 bit, IPv4, là ints. Tôi nghi ngờ IPv6 là giá trị 64 bit, nhưng tôi đã không sử dụng bản thân mình –

3

Sử dụng Spring IpAddressMatcher. Không giống như Apache Commons Net, nó hỗ trợ cả ipv4 và ipv6.

import org.springframework.security.web.util.matcher.IpAddressMatcher; 
... 

private void checkIpMatch() { 
    matches("192.168.2.1", "192.168.2.1"); // true 
    matches("192.168.2.1", "192.168.2.0/32"); // false 
    matches("192.168.2.5", "192.168.2.0/24"); // true 
    matches("92.168.2.1", "fe80:0:0:0:0:0:c0a8:1/120"); // false 
    matches("fe80:0:0:0:0:0:c0a8:11", "fe80:0:0:0:0:0:c0a8:1/120"); // true 
    matches("fe80:0:0:0:0:0:c0a8:11", "fe80:0:0:0:0:0:c0a8:1/128"); // false 
    matches("fe80:0:0:0:0:0:c0a8:11", "192.168.2.0/32"); // false 
} 

private boolean matches(String ip, String subnet) { 
    IpAddressMatcher ipAddressMatcher = new IpAddressMatcher(subnet); 
    return ipAddressMatcher.matches(ip); 
} 

Nguồn: here

0

Để kiểm tra Một IP trong một mạng con, tôi đã sử dụng phương pháp isInRange trong lớp SubnetUtils. Nhưng phương pháp này có một lỗi rằng nếu subnet của bạn là X, mỗi địa chỉ IP thấp hơn X, isInRange trả về true. Ví dụ nếu subnet của bạn là 10.10.30.0/24 và bạn muốn kiểm tra 10.10.20.5, phương thức này trả về true. Để đối phó với lỗi này, tôi sử dụng mã dưới đây.

public static void main(String[] args){ 
    String list = "10.10.20.0/24"; 
    String IP1 = "10.10.20.5"; 
    String IP2 = "10.10.30.5"; 
    SubnetUtils subnet = new SubnetUtils(list); 
    SubnetUtils.SubnetInfo subnetInfo = subnet.getInfo(); 
    if(MyisInRange(subnetInfo , IP1) == true) 
     System.out.println("True"); 
    else 
     System.out.println("False"); 
    if(MyisInRange(subnetInfo , IP2) == true) 
     System.out.println("True"); 
    else 
     System.out.println("False"); 
} 

private boolean MyisInRange(SubnetUtils.SubnetInfo info, String Addr) 
{ 
    int address = info.asInteger(Addr); 
    int low = info.asInteger(info.getLowAddress()); 
    int high = info.asInteger(info.getHighAddress()); 
    return low <= address && address <= high; 
}