我考虑拨打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
}
答案 0 :(得分:6)
只需递增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
答案 1 :(得分:1)
我会在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
}
答案 2 :(得分:0)
如果你只需要计算下一个IP地址,下面的函数nextIP()就可以了。
用法:
// output is 1.0.1.0
fmt.Println(nextIP(net.ParseIP("1.0.0.255"), 1))
nextIP():
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
答案 3 :(得分:0)
我刚刚遇到过这个问题,我想分享一下我的解决方案。它效率不高,但在几行中解决了这个问题。
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)
}