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

发布于 2024-07-06 07:21:11 字数 170 浏览 13 评论 0原文

因此,您有一个从管理 Web UI 检索的字符串(因此它绝对是一个字符串)。 在 Java 中如何判断该字符串是 IP 地址还是主机名?

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

So you have a String that is retrieved from an admin web UI (so it is definitely a String). How can you find out whether this string is an IP address or a hostname in Java?

Update: I think I didn't make myself clear, I was more asking if there is anything in the Java SDK that I can use to distinguish between IPs and hostnames? Sorry for the confusion and thanks for everybody who took/will take the time to answer this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

空心↖ 2024-07-13 07:21:11

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

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

You can use a regular expression with this pattern:

\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

That will tell you if it's an IPv4 address.

荆棘i 2024-07-13 07:21:11

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

Do we get to make the assumption that it is one or the other, and not something completely different? If so, I'd probably use a regex to see if it matched the "dotted quad" format.

桜花祭 2024-07-13 07:21:11

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

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

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

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

You can see if the string matches the number.number.number.number format, for example:

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

will match anything from 0 - 999.

Anything else you can have it default to hostname.

长梦不多时 2024-07-13 07:21:11
URI validator = new URI(yourString);

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

如果您试图区分两者......那么我错过了阅读您的问题。

URI validator = new URI(yourString);

That code will validate the IP address or Hostname. (It throws a malformed URI Exception if the string is invalid)

If you are trying to distinguish the two..then I miss read your question.

就是爱搞怪 2024-07-13 07:21:11

您可以通过 InetAddress.getByName(addr) 调用使用安全管理器。

如果 addr 不是点分四边形,getByName 将尝试执行连接来进行名称查找,安全管理器可以将其捕获为 checkConnect(addr, -1) 调用,导致抛出一个您可以捕获的 SecurityException。

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

You can use a security manager with the InetAddress.getByName(addr) call.

If the addr is not a dotted quad, getByName will attempt to perform a connect to do the name lookup, which the security manager can capture as a checkConnect(addr, -1) call, resulting in a thrown SecurityException that you can catch.

You can use System.setSecurityManager() if you're running fully privileged to insert your custom security manager before the getByName call is made.

不交电费瞎发啥光 2024-07-13 07:21:11

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

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

It is not as simple as it may appear, there are some ambiguities around characters like hyphens, underscore, and square brackets '-', '_', '[]'.

The Java SDK is has some limitations in this area. When using InetAddress.getByName it will go out onto the network to do a DNS name resolution and resolve the address, which is expensive and unnecessary if all you want is to detect host vs address. Also, if an address is written in a slightly different but valid format (common in IPv6) doing a string comparison on the results of InetAddress.getByName will not work.

The IPAddress Java library will do it. The javadoc is available at the link. Disclaimer: I am the project manager.

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);  
}

Output:

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
ぃ弥猫深巷。 2024-07-13 07:21:11

你不能直接对其进行正则表达式匹配吗?

Couldn't you just to a regexp match on it?

别再吹冷风 2024-07-13 07:21:11

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

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

Use InetAddress#getAllByName(String hostOrIp) - if hostOrIp is an IP-address the result is an array with single InetAddress and it's .getHostAddress() returns the same string as 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);
        }
    }
}

The output:

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
心房敞 2024-07-13 07:21:11

如果指定了主机名,此代码仍然执行 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)

Do you think we can Expect the toString() 行为很快就会改变?

This code still performs the DNS lookup if a host name is specified, but at least it skips the reverse lookup that may be performed with other approaches:

   ...
   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;
}

It generates this output:

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

Do you think we can expect the toString() behavior to change anytime soon?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文