如何获得下一个IP地址?

时间:2015-07-02 17:48:48

标签: go ip

我考虑拨打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
}

4 个答案:

答案 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)
}