3 回答
TA贡献1765条经验 获得超5个赞
jimt 的回答是正确的,但相当复杂。我会简单地检查ip.To4() != nil
。由于文档说“如果 ip 不是 IPv4 地址,To4 返回 nil”这个条件应该返回true
当且仅当地址是 IPv4 地址。
TA贡献1824条经验 获得超8个赞
IP 的长度几乎总是 16,因为 的内部表示net.IP对于任何一种情况都是相同的。从文档:
请注意,在本文档中,将 IP 地址称为 IPv4 地址或 IPv6 地址是地址的语义属性,而不仅仅是字节切片的长度:16 字节切片仍然可以是 IPv4 地址。
区分这两种类型取决于 IP 是如何初始化的。查看 的代码net.IPv4(),您可以看到它被初始化为 16 个字节,其中前 12 个字节设置为 的值v4InV6Prefix。
// IPv4 returns the IP address (in 16-byte form) of the
// IPv4 address a.b.c.d.
func IPv4(a, b, c, d byte) IP {
p := make(IP, IPv6len)
copy(p, v4InV6Prefix)
p[12] = a
p[13] = b
p[14] = c
p[15] = d
return p
}
其中v4InV6Prefix定义为:
var v4InV6Prefix = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
如果您想要可靠的区分,请查看源如何net.IP.To4处理它:
// To4 converts the IPv4 address ip to a 4-byte representation.
// If ip is not an IPv4 address, To4 returns nil.
func (ip IP) To4() IP {
if len(ip) == IPv4len {
return ip
}
if len(ip) == IPv6len &&
isZeros(ip[0:10]) &&
ip[10] == 0xff &&
ip[11] == 0xff {
return ip[12:16]
}
return nil
}
isZeros未导出,因此您必须在本地复制该代码。然后您可以简单地执行与上述相同的操作来确定您使用的是 IPv4 还是 IPv6。
TA贡献1816条经验 获得超4个赞
该接受的答案由埃文(ip.To4() != nil
)解决问题。然而,已经有一些评论和其他答案检查表示是 IPv4 还是 IPv6 并且它们并不总是准确的:
注意:下面分别列出了几个有效的 IPv4 和 IPv6 有效符号列表。每个条目都代表第一个基本条目的变化。可以根据需要组合这些变体,但出于空间原因,除了消除歧义之外,没有列出变体组合。
有效的 IPv4 符号:
"192.168.0.1"
: 基本的"192.168.0.1:80"
: 带有端口信息
有效的 IPv6 符号:
"::FFFF:C0A8:1"
: 基本的"::FFFF:C0A8:0001"
: 前导零"0000:0000:0000:0000:0000:FFFF:C0A8:1"
: 双冒号展开"::FFFF:C0A8:1%1"
: 带区域信息"::FFFF:192.168.0.1"
: IPv4 字面量"[::FFFF:C0A8:1]:80"
: 带有端口信息"[::FFFF:C0A8:1%1]:80"
: 带区域和端口信息
所有这些情况(同时支持IPv4和IPv6名单)将被考虑IPv4地址的net
包。IPv6 列表的 IPv4 文字变体将被govalidator视为 IPv4 。
检查它是 IPv4 还是 IPv6 地址的最简单方法如下:
import strings
func IsIPv4(address string) bool {
return strings.Count(address, ":") < 2
}
func IsIPv6(address string) bool {
return strings.Count(address, ":") >= 2
}
- 3 回答
- 0 关注
- 281 浏览
添加回答
举报