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

How do you tell whether a string is an IP or a hostname

提问人: 提问时间:9/16/2008 最后编辑:4 revs, 3 users 100%user10059 更新时间:9/5/2020 访问量:4261

问:

因此,您有一个从管理 Web UI 检索的 String(因此它肯定是一个 String)。你怎么能知道这个字符串是 IP 地址还是 Java 中的主机名?

更新:我想我没有说清楚,我更多的是问 Java SDK 中是否有任何可以用来区分 IP 和主机名的东西?很抱歉造成混乱,并感谢所有花时间回答这个问题的人。

Java IP 地址 主机名

评论


答:

15赞 Sam 9/16/2008 #1

您可以将正则表达式与以下模式一起使用:

\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 地址。

评论

0赞 DevelopingChris 9/16/2008
我认为仅仅测试数字模式就足够了,如果你需要真正的范围验证,正则表达式真的不是最好的方法。
0赞 Jesse Barnum 2/28/2021
不起作用。当我将您的正则表达式复制并粘贴到 regex101.com 中,并搜索字符串 192.168.1.1 时,它说不匹配。
2赞 zxcv 9/16/2008 #2

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

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

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

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

评论

0赞 Vagnerr 9/16/2008
999.999.999.999 不是有效的 IP 格式。您的正则表达式需要更具体
5赞 DevelopingChris 9/16/2008
也不要认为它是一个有效的主机名
2赞 Joel Coehoorn 9/16/2008 #3

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

0赞 davetron5000 9/16/2008 #4

你不能只在上面进行正则表达式匹配吗?

1赞 jjnguy 9/16/2008 #5
URI validator = new URI(yourString);

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

如果你想区分这两者..然后我想念阅读你的问题。

1赞 davenpcj 9/16/2008 #6

您可以在通话中使用安全管理器。InetAddress.getByName(addr)

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

如果运行的是完全特权,则可以在进行调用之前插入自定义安全管理器。System.setSecurityManager()getByName

1赞 Sean F #7

它并不像看起来那么简单,连字符、下划线和方括号“-”、“_”、“[]”等字符存在一些歧义。

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

IPAddress Java 库将执行此操作。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
0赞 Denis Kalinin #8

使用 InetAddress#getAllByName(String hostOrIp) - 如果是 IP 地址,则结果是一个具有单个 InetAddress 的数组,它返回与 相同的字符串。hostOrIp.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
0赞 BillS #9

如果指定了主机名,此代码仍会执行 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() 行为很快改变吗?