如何判断字符串是IP还是主机名

时间:2008-09-15 21:01:02

标签: java ip-address hostname

所以你有一个从管理员web UI中检索到的String(所以它绝对是一个String)。如何确定此字符串是Java中的IP地址还是主机名?

更新:我想我没有说清楚,我更想问Java SDK中是否有可以用来区分IP和主机名的东西?对于所有采取/将花时间回答此问题的人感到困惑和感谢。

9 个答案:

答案 0 :(得分:14)

您可以使用具有此模式的正则表达式:

\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

这将告诉您它是否是IPv4地址。

答案 1 :(得分:2)

您可以查看字符串是否与number.number.number.number格式匹配,例如:

\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b

将匹配0 - 999中的任何内容。

您可以将其他任何内容默认为主机名。

答案 2 :(得分:2)

我们是否可以假设它中的一个,而不是完全不同的东西?如果是这样,我可能会使用正则表达式来查看它是否与“点四元”格式匹配。

答案 3 :(得分:1)

URI validator = new URI(yourString);

该代码将验证IP地址或主机名。 (如果字符串无效,则抛出格式错误的URI异常)

如果你想区分这两个......那我就错过了你的问题。

答案 4 :(得分:0)

难道你不能只进行正则表达式匹配吗?

答案 5 :(得分:0)

您可以使用InetAddress.getByName(addr)来电的安全管理员。

如果addr不是虚线四边形,getByName将尝试执行连接以执行名称查找,安全管理器可以将其作为checkConnect(addr, -1)调用捕获,从而导致抛出SecurityException,你可以抓住。

如果您在System.setSecurityManager()来电之前运行完全特权以插入自定义安全管理器,则可以使用getByName

答案 6 :(得分:0)

它并不像看起来那么简单,像连字符,下划线和方括号' - ','_','[]'这样的字符有一些含糊之处。

Java SDK在这方面有一些局限性。当使用InetAddress.getByName时,它将进入网络以进行DNS名称解析并解析地址,如果你想要的只是检测主机与地址,这是昂贵且不必要的。此外,如果地址以稍微不同但有效的格式(在IPv6中很常见)写入,则对InetAddress.getByName的结果进行字符串比较将不起作用。

The IPAddress Java library会这样做。链接中提供了javadoc。免责声明:我是项目经理。

static void check(HostName host) {
    try {
        host.validate();
        if(host.isAddress()) {
            System.out.println("address: " + host.asAddress());
        } else {
            System.out.println("host name: " + host);
        }
    } catch(HostNameException e) {
        System.out.println(e.getMessage());
    }
}

public static void main(String[] args) {
    HostName host = new HostName("1.2.3.4");
    check(host);
    host = new HostName("1.2.a.4");
    check(host);
    host = new HostName("::1");
    check(host);
    host = new HostName("[::1]");
    check(host);
    host = new HostName("1.2.?.4");
    check(host);  
}

输出:

address: 1.2.3.4
host name: 1.2.a.4
address: ::1
address: ::1
1.2.?.4 Host error: invalid character at index 4

答案 7 :(得分:0)

使用InetAddress#getAllByName(String hostOrIp)-如果hostOrIp是IP地址,则结果是具有单个InetAddress的数组,并且.getHostAddress()返回与hostOrIp相同的字符串。

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

public class IPvsHostTest {
    private static final org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(IPvsHostTest.class);

    @org.junit.Test
    public void checkHostValidity() {
        Arrays.asList("10.10.10.10", "google.com").forEach( hostname -> isHost(hostname));
    }
    private void isHost(String ip){
        try {
            InetAddress[] ips = InetAddress.getAllByName(ip);
            LOG.info("IP-addresses for {}", ip);
            Arrays.asList(ips).forEach( ia -> {
                LOG.info(ia.getHostAddress());
            });
        } catch (UnknownHostException e) {
            LOG.error("Invalid hostname", e);
        }
    }
}

输出:

IP-addresses for 10.10.10.10
10.10.10.10
IP-addresses for google.com
64.233.164.100
64.233.164.138
64.233.164.139
64.233.164.113
64.233.164.102
64.233.164.101

答案 8 :(得分:0)

如果指定了主机名,此代码仍将执行DNS查找,但至少它会跳过使用其他方法可能执行的反向查找:

   ...
   isDottedQuad("1.2.3.4");
   isDottedQuad("google.com");
   ...

boolean isDottedQuad(String hostOrIP) throws UnknownHostException {
   InetAddress inet = InetAddress.getByName(hostOrIP);
   boolean b = inet.toString().startsWith("/");
   System.out.println("Is " + hostOrIP + " dotted quad? " + b + " (" + inet.toString() + ")");
   return b;
}

它生成以下输出:

Is 1.2.3.4 dotted quad? true (/1.2.3.4)
Is google.com dotted quad? false (google.com/172.217.12.238)

您认为我们可以期望toString()行为很快改变吗?