【问题标题】:How do you tell whether a string is an IP or a hostname如何判断字符串是 IP 还是主机名
【发布时间】:2010-09-09 04:15:15
【问题描述】:

所以你有一个从管理 Web UI 检索到的字符串(所以它肯定是一个字符串)。在 Java 中如何判断这个字符串是 IP 地址还是主机名?

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

【问题讨论】:

    标签: java ip-address hostname


    【解决方案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 地址。

    【讨论】:

    • 我认为只测试数字模式就足够了,如果您需要真正的范围验证,正则表达式确实不是最好的方法。
    • 不起作用。当我将您的 RegEx 复制并粘贴到 regex101.com 并搜索字符串 192.168.1.1 时,它显示不匹配。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

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

      您可以将其默认为主机名。

      【讨论】:

      • 999.999.999.999 不是有效的 ip 格式。您的正则表达式需要更具体
      • 也不认为它是一个有效的主机名
      【解决方案4】:
      URI validator = new URI(yourString);
      

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

      如果您想区分这两者..那么我想念您的问题。

      【讨论】:

        【解决方案5】:

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

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

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

        【讨论】:

          【解决方案6】:

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

          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】:

            你不能只用一个正则表达式匹配它吗?

            【讨论】:

              【解决方案8】:

              使用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】:

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

                【讨论】:

                  猜你喜欢
                  • 2021-06-22
                  • 1970-01-01
                  • 2012-04-14
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2014-12-16
                  • 1970-01-01
                  相关资源
                  最近更新 更多