轉載:https://blog.thinkeridea.com/201903/go/ip2long.htmlhtml
IP 地址庫中 IP 地址的保存格式通常有兩種,一種是點分十進制形式(192.168.1.1),另外一種是數字形式(3232235777),應用中,常常須要在這兩種格式之間作轉換。git
針對這一個問題我在 exnet 擴展包裏面實現可二者的轉換的快捷方法:github
func IP2Long(ip net.IP) (uint, error)
IP2Long 把 net.IP 轉爲數值func Long2IP(i uint) (net.IP, error)
Long2IP 把數值轉爲 net.IPfunc IPString2Long(ip string) (uint, error)
IPString2Long 把 ip 字符串轉爲數值func Long2IPString(i uint) (string, error)
Long2IPString 把數值轉爲 ip 字符串使用示例:ide
package main import ( "fmt" "net" "reflect" "github.com/thinkeridea/go-extend/exnet" ) func main() { ip := "192.168.1.1" n, _ := exnet.IPString2Long(ip) s, _ := exnet.Long2IPString(n) fmt.Println(n, s == ip) Ip1 := net.ParseIP(ip) // 會獲得一個16字節的byte,主要爲了兼容ipv6 n, _ = exnet.IP2Long(Ip1) Ip2, _ := exnet.Long2IP(n) fmt.Println(n, reflect.DeepEqual(Ip1[12:], Ip2)) }
那麼是如何將點分十進制的IP地址轉爲數字?<br/>
IPv4 地址有4個字節,樣式以下: <br/>
MSB————–LSB <br/>
b4 b3 b2 b1 <br/>ui
每一個字節表示的範圍:idea
通用公式:b4<<24 | b3<<16 | b2<<16 | b1
<br/>
例如,222.173.108.86 <br/>
轉換方法:222<<24 | 173<<16 | 108<<8 | 86 = 3735907414
<br/>
再例如,1.0.1.1 <br/>
轉換方法:1<<24 | 0<<16 | 1<<8 | 1 = 16777473
<br/>code
exnet 中實現以下:orm
// IPString2Long 把ip字符串轉爲數值 func IPString2Long(ip string) (uint, error) { b := net.ParseIP(ip).To4() if b == nil { return 0, errors.New("invalid ipv4 format") } return uint(b[3]) | uint(b[2])<<8 | uint(b[1])<<16 | uint(b[0])<<24, nil }
把數值轉換爲字符串的邏輯翻轉過來便可, exnet 中實現以下:htm
// Long2IPString 把數值轉爲ip字符串 func Long2IPString(i uint) (string, error) { if i > math.MaxUint32 { return "", errors.New("beyond the scope of ipv4") } ip := make(net.IP, net.IPv4len) ip[0] = byte(i >> 24) ip[1] = byte(i >> 16) ip[2] = byte(i >> 8) ip[3] = byte(i) return ip.String(), nil }
轉載:blog
本文做者: 戚銀(thinkeridea)
本文連接: https://blog.thinkeridea.com/201903/go/ip2long.html
版權聲明: 本博客全部文章除特別聲明外,均採用 CC BY 4.0 CN協議 許可協議。轉載請註明出處!