有效 IP 字符串中的“:”是否足以确定它是 IPv6 地址?

Is ":" in a valid IP string sufficient to determine it is an IPv6 address?

给定一个 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)。

注意:这个 "optimization" 是指我知道 IP 字符串是 已经过检查和验证的 IP 地址这一事实。

有一个问题,如果您使用 InetAddress,仅检查 : 是不够的。

::ffff:<IPv4 Address> 模式的地址被视为 IPv4 地址。例如,下面调用 returns 和 Inet4Address:

InetAddress.getByName("::ffff:1.2.3.4")

同一地址的所有变体也是如此,例如::0:ffff:1.2.3.4

来自documentation of Inet6Address

IPv4-mapped address
Of the form::ffff:w.x.y.z, this IPv6 address is used to represent an IPv4 address. It allows the native program to use the same address data structure and also the same socket when communicating with both IPv4 and IPv6 nodes.

In InetAddress and Inet6Address, it is used for internal representation; it has no functional role. Java will never return an IPv4-mapped address. These classes can take an IPv4-mapped address as input, both in byte array and text representation. However, it will be converted into an IPv4 address.

这似乎是唯一的例外。

IPv6 地址字符串将包含 两个七个 之间的冒号,不一定是连续的。但是,如果您已经在别处验证了地址,那么检查是否存在冒号就足够了。

但是如果您已经有一个 InetAddress 对象,请坚持使用 instanceof。来回转换为字符串听起来像是很多不必要的工作。