代码之家  ›  专栏  ›  技术社区  ›  Community wiki

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

  •  4
  • Community wiki  · 技术社区  · 3 年前

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

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

    9 回复  |  直到 3 年前
        1
  •  15
  •   Patrick D'Souza ob1    13 年前

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

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

        2
  •  2
  •   Joel Coehoorn    18 年前

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

        3
  •  2
  •   Patrick D'Souza ob1    13 年前

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

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

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

    您可以将其默认为hostname。

        4
  •  1
  •   jjnguy Julien Chastang    18 年前
    URI validator = new URI(yourString);
    

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

    如果你想把两者区别开来。。那么我错过了阅读你的问题。

        5
  •  1
  •   Patrick D'Souza ob1    13 年前

    您可以将安全管理器与 InetAddress.getByName(addr) 呼叫

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

    您可以使用 System.setSecurityManager() 如果您运行的是完全有权限在 getByName 发出呼叫。

        6
  •  1
  •   Sean F    9 年前

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

    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
  •   davetron5000    18 年前

    你就不能在上面匹配一个正则表达式吗?

        8
  •  0
  •   Denis Kalinin    7 年前

    使用 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
    
        9
  •  0
  •   BillS    6 年前

    如果指定了主机名,此代码仍然执行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()行为在短期内发生变化吗?

    推荐文章