亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

golang區分IPv4 IPv6

golang區分IPv4 IPv6

Go
慕娘9325324 2021-07-30 14:02:43
對于我正在開發的程序,我必須檢查 IP(將我連接到 Internet 的 IP)是公共的還是私有的。為此,我需要區分 IP 是 IPv4 還是 IPv6。我想通過 IP 的長度來檢查它:conn, err := net.Dial("udp", "8.9.10.11:2342")if err != nil {    fmt.Println("Error", err)}localaddr := conn.LocalAddr()addr, _ := net.ResolveUDPAddr("udp", localaddr.String())ip := addr.IPfmt.Println(ip)fmt.Println(len(ip))好吧,我的 IP 是 192.168.2.100,所以是 IPv4,但是 len(ip) 告訴我長度是 16,這就是 IPv6。我的錯誤是什么?是否存在任何其他方法來區分始終有效的 IPv4 和 IPv6?
查看完整描述

3 回答

?
POPMUISE

TA貢獻1765條經驗 獲得超5個贊

jimt 的回答是正確的,但相當復雜。我會簡單地檢查ip.To4() != nil。由于文檔說“如果 ip 不是 IPv4 地址,To4 返回 nil”這個條件應該返回true當且僅當地址是 IPv4 地址。


查看完整回答
反對 回復 2021-08-02
?
有只小跳蛙

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。


查看完整回答
反對 回復 2021-08-02
?
繁華開滿天機

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

}


查看完整回答
反對 回復 2021-08-02
  • 3 回答
  • 0 關注
  • 344 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號