[英]How to get the next IP address?
我正在考慮調用net.IP.String()
, strings.Split(ip, ".")
,一些代碼來計算所有極端情況,最后net.ParseIP(s)
。 有沒有更好的方法呢? 以下是我當前實現的代碼(未處理特殊情況)。
package main
import (
"fmt"
"net"
"strconv"
"strings"
)
func main() {
ip := net.ParseIP("127.1.0.0")
next, err := NextIP(ip)
if err != nil {
panic(err)
}
fmt.Println(ip, next)
}
func NextIP(ip net.IP) (net.IP, error) {
s := ip.String()
sa := strings.Split(s, ".")
i, err := strconv.Atoi(sa[2])
if err != nil {
return nil, err
}
i++
sa[3] = strconv.Itoa(i)
s = strings.Join(sa, ".")
return net.ParseIP(s), nil
}
只需增加 IP 地址中的最后一個八位字節
ip := net.ParseIP("127.1.0.0")
// make sure it's only 4 bytes
ip = ip.To4()
// check ip != nil
ip[3]++ // check for rollover
fmt.Println(ip)
//127.1.0.1
然而,這在技術上是不正確的,因為 127.1.0.1/8 子網中的第一個地址是 127.0.0.1。 要獲得真正的“第一個”地址,您還需要一個 IPMask。 由於您沒有指定一個,您可以將 DefaultMask 用於 IPv4 地址(對於 IPv6,您不能假定掩碼,您必須提供它)。
http://play.golang.org/p/P_QWwRIBIm
ip := net.IP{192, 168, 1, 10}
ip = ip.To4()
if ip == nil {
log.Fatal("non ipv4 address")
}
ip = ip.Mask(ip.DefaultMask())
ip[3]++
fmt.Println(ip)
//192.168.1.1
如果您只需要計算下一個 IP 地址,下面的 function nextIP() 就可以解決問題。
用法:
// output is 1.0.1.0
fmt.Println(nextIP(net.ParseIP("1.0.0.255"), 1))
下一個IP():
func nextIP(ip net.IP, inc uint) net.IP {
i := ip.To4()
v := uint(i[0])<<24 + uint(i[1])<<16 + uint(i[2])<<8 + uint(i[3])
v += inc
v3 := byte(v & 0xFF)
v2 := byte((v >> 8) & 0xFF)
v1 := byte((v >> 16) & 0xFF)
v0 := byte((v >> 24) & 0xFF)
return net.IPv4(v0, v1, v2, v3)
}
游樂場: https://play.golang.org/p/vHrmftkVjn2
要點: https://gist.github.com/udhos/b468fbfd376aa0b655b6b0c539a88c03
在 IP 增加之后,我將針對 CIDR 進行測試,因此溢出不會改變預期的子網。
func incrementIP(origIP, cidr string) (string, error) {
ip := net.ParseIP(origIP)
_, ipNet, err := net.ParseCIDR(cidr)
if err != nil {
return origIP, err
}
for i := len(ip) - 1; i >= 0; i-- {
ip[i]++
if ip[i] != 0 {
break
}
}
if !ipNet.Contains(ip) {
return origIP, errors.New("overflowed CIDR while incrementing IP")
}
return ip.String(), nil
}
剛才也遇到了這個問題,想分享一下我的解決方法。 它不是那么有效,但只需幾行就解決了問題。
func nextIP(ip net.IP) net.IP {
// Convert to big.Int and increment
ipb := big.NewInt(0).SetBytes([]byte(ip))
ipb.Add(ipb, big.NewInt(1))
// Add leading zeros
b := ipb.Bytes()
b = append(make([]byte, len(ip)-len(b)), b...)
return net.IP(b)
}
使用IPAddress Go 庫,這很簡單,適用於 IPv4 和 IPv6,並處理極端情況。 免責聲明:我是項目經理。
import (
"fmt"
"github.com/seancfoley/ipaddress-go/ipaddr"
)
func main() {
fmt.Println(increment("127.0.0.1"))
fmt.Println(increment("127.0.0.255"))
fmt.Println(increment("::1"))
fmt.Println(increment("255.255.255.255"))
}
func increment(addrString string) *ipaddr.IPAddress {
addr := ipaddr.NewIPAddressString(addrString).GetAddress()
return addr.Increment(1)
}
Output:
127.0.0.2
127.0.1.0
::2
<nil>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.