将IP地址匹配到子网掩码表中……Java的最佳方法是什么?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将IP地址匹配到子网掩码表中……Java的最佳方法是什么?相关的知识,希望对你有一定的参考价值。
这里是场景...我有一个子网表。 (见下文)我有一个IP地址。我想根据表中的查询来找出IP地址属于哪个子网。然后将使用此关联来确定用户所处的位置。这是一个专用网络空间,因此标准Internet到位置查找将不适用。最好的方法是什么?我需要将ip地址分解成数字部分,然后与所有子网进行按位比较..还是Java API中有内置工具,可以使我将IP地址与子网掩码进行比较变得更加轻松?
我主要是寻找将ipaddress与给定子网掩码进行比较的最佳方法,并确定是此匹配项,否则确定不匹配。也将不胜感激关于如何以最少的操作存储列表和搜索的任何技巧。
理想情况下,我会做类似的事情:
List subnetInfo = null;
subnetInfo = findSubnet('192.168.0.1'); //value null if nothing found
....
//return null if nothing found
List findSubnet(String ipaddress) {
List subnetDetails = null;
.... code here ...
return subnetDetails;
}
表1:子网示例列表
dk-ballerup-gen-off-v411 10.172.80.0/21 NANR-denmark-ballerup-metallbuen66-ground-first-floors-incl-dhcp-(sr14585203)
ae-dubai-ofssl-gen-off-v410 10.172.88.0/24 NANR-arab-emirates-ofssl-iflex-general-office-v410-(sr12781477)
ru-stpetersburg-gen-off-v411 10.172.89.0/24 NANR-russia-stpetersburg-general-office-incl-dhcp (bsteinba)
Apache Commons Net对于这种情况具有SubnetUtils,包括确定给定IP地址是否在给定子网内。
示例:
String[] subnetsMasks = { ... };
Collection<SubnetInfo> subnets = new ArrayList<SubnetInfo>();
for (String subnetMask : subnetsMasks) {
subnets.add(new SubnetUtils(subnetMask).getInfo());
}
String ipAddress = ...;
for (SubnetInfo subnet : subnets) {
if (subnet.isInRange(ipAddress)) {
System.out.println("IP Address " + ipAddress + " is in range " + subnet.getCidrSignature());
}
}
请记住,由于历史原因,该IP地址只是int
值,以十进制形式的4个八位字节表示。
对于同一令牌,子网实际上是从网络地址到广播地址的连续ints
范围。
因此,如果您的IP地址对象具有int转换器,则可以通过简单的int比较来简单地检查该整数是否在子网范围内。
如果表是SQL表,而数据库是PostgreSql,则可以使用PostgreSQL types和functions。
好很多条件...
将IP地址和网络掩码转换为整数,然后将它们与在一起。如果结果等于IP地址,则它是该网络掩码中的地址。请注意,如果网络掩码不是唯一的,则可能会获得多个匹配项。
这是一个古老的问题,但我认为值得给别人减轻它给我带来的痛苦。
避开Apache Commons Net SubnetUtils类,这是越野车:
我面临与您相同的问题,但仅限于private networks(192.168.X.X, 10.x.x.x, ...
和IPv6)。
如果您也仅限于这种情况,则应使用内置的InetAddress.isSiteLocalAddress()
我基于skaffman解决方案构建了一种方法。对于那些对复制粘贴解决方案感兴趣的人:
InetAddress.isSiteLocalAddress()
最好的方法是使用地址Trie并同时检查所有地址中是否包含。 /**
* Checks if client ip equals or is in range of ip networks provided by
* semicolon separated list
*
* @param clientIp in numeric form like "192.168.0.10"
* @param ipList like "127.0.0.1;192.168.0.0/24;10.0.0.0/8"
* @return true if client ip from the list os ips and networks
*/
protected boolean evaluateIp(String clientIp, String ipList) {
BusinessLogger log = getLog();
log.debug("Evaluate ip ");
if (ipList == null) {
log.info("No ip address provided in ApiPrivilege");
return false;
}
String[] subnetMasks = ipList.split(";");
for (String subnetMask : subnetMasks) {
subnetMask = subnetMask.trim();
if (eq(subnetMask, clientIp))
return true;
if (subnetMask.contains("/")) {
if (new SubnetUtils(subnetMask).getInfo().isInRange(clientIp))
return true;
}
}
return false;
}
提供了对IPv4和IPv6执行此操作的方法。免责声明:我是项目经理。
The IPAddress Java library
输出:
String subnets[] = { "10.172.80.0/21", "10.172.88.0/24", "10.172.89.0/24" };
IPv4AddressTrie blocksTrie = new IPv4AddressTrie();
for(String str : subnets) {
blocksTrie.add(new IPAddressString(str).getAddress().toIPv4());
}
IPAddressString toFindAddrStr = new IPAddressString("10.172.88.3");
IPv4Address toFindBlockFor = toFindAddrStr.getAddress().toIPv4();
IPv4TrieNode containingNode = blocksTrie.elementsContaining(toFindBlockFor);
System.out.println("For address " + toFindBlockFor + " containing block is " +
containingNode.toTreeString(false, false) + "
");
该地址还提供了一种检查收容的方法,例如:For address 10.172.88.3 containing block is
● 10.172.88.0/24
将以下jar包含在pom.xml中
How to check if an IP address is from a particular network/netmask in Java?
Spring提供了上述库来支持ipv4和ipv6。
下面是检查ip是否属于给定子网的代码段。
*<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.0.7.RELEASE</version>
</dependency>*
以上是关于将IP地址匹配到子网掩码表中……Java的最佳方法是什么?的主要内容,如果未能解决你的问题,请参考以下文章