Tôi cần xác định xem địa chỉ IP đã cho có từ một số mạng đặc biệt nào đó mà tôi phải xác thực tự động hay không.Có ai biết một thành phần java để kiểm tra xem địa chỉ IP là từ mạng cụ thể/netmask?
Trả lời
Jakarta Commons Net có org.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.
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;
IP và netmask có phải là ints hoặc longs không? – simgineer
Đị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 –
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
Để 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;
}
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
@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