IP的長度幾乎總是16,因爲無論哪種情況,net.IP
的內部表示都是相同的。從the documentation:
注意,本文檔中,指的是一個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。
顯然,這並不總是準確:https://github.com/asaskevich/govalidator/pull/100 – tmm1
添加@ tmm1的評論,該鏈接中提出的解決方案也不總是準確的。 ':: FFFF:127.0.0.1'是一個有效的IPv6表示,當它返回False時返回'Is'作爲'IsIPv4()'。 – Adirio
最初的問題不是關於*表示*是以v4還是v6的形式出現,而是*地址*是否是有效的v4或v6地址。 ':: FFFF:'是v4InV6Prefix,所以':: FFFF:127.0.0.1'實際上是一個有效的IPv4地址,用於所有的意圖和目的。 – Evan