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 有效符號列表。每個條目都代表第一個基本條目的變化??梢愿鶕枰M合這些變體,但出于空間原因,除了消除歧義之外,沒有列出變體組合。
有效的 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 關注
- 344 瀏覽
添加回答
舉報