给定一个100%明确地为有效 IP地址的字符串。
但是,接收它作为参数的方法不会收到一个额外的参数,告诉它是IPv4还是IPv6。
我已经看到了一种确定IPv4或IPv6的方法:
InetAddress address = InetAddress.getByName(ip);
if (address instanceof Inet6Address) {
// It's ipv6
} else if (address instanceof Inet4Address) {
// It's ipv4
}
但我正在寻找一种更快的方式(注意上面也应该用try / catch包围)。
我可以通过以下简单的方式逃脱:
if (totallyValidIp.contains(":") {
// It's ipv6
}
else {
// It's ipv4
}
还是有一个我不知道的渔获物? (例如,有效的IPv6不包含任何“:”)。
注意:这种“优化”指的是我知道IP字符串是已经检查和验证的 IP地址的事实。
答案 0 :(得分:3)
IPv6地址字符串将包含两个和七个冒号,不一定是连续的。但是如果你已经在其他地方验证了地址,那么检查是否存在冒号就足够了。
但是,如果您已经拥有InetAddress
个对象,请坚持使用instanceof
。来回转换为字符串听起来像很多不必要的工作。
答案 1 :(得分:2)
有一个问题,如果您使用:
,仅检查InetAddress
是不够的。
模式::ffff:<IPv4 Address>
的地址被视为IPv4地址。例如,以下调用返回Inet4Address
:
InetAddress.getByName("::ffff:1.2.3.4")
同一地址的所有变体都是如此,例如::0:ffff:1.2.3.4
。
来自documentation of Inet6Address:
IPv4映射地址
在:: ffff:w.x.y.z形式中,此IPv6地址用于表示IPv4地址。它允许本机程序在与IPv4和IPv6节点通信时使用相同的地址数据结构和相同的套接字。在InetAddress和Inet6Address中,它用于内部表示;它没有任何功能。 Java将永远不会返回IPv4映射地址。这些类可以将IPv4映射地址作为输入,包括字节数组和文本表示形式。但是,它将被转换为IPv4地址。
这似乎是唯一的例外。