计算给定CIDR的下一个CIDR,其中CIDR的最后一位比给定CIDR的最后一位少一位。

huangapple go评论73阅读模式
英文:

Go - calculate the cidr below one bit of the cidr provided

问题

问题:

如何计算给定CIDR下一个比提供的CIDR小一位的CIDR?

给定:

一个网络CIDR:(192.168.0.0/16)

期望结果:

192.168.0.0/17, 192.168.128.0/17

使用默认的net包和github.com/brotherpowers/ipsubnetgithub.com/seancfoley/ipaddress-go/ipaddr等包未能得到期望的结果。

英文:

Ask

How do you calculate the cidr below one bit of the cidr provided?

Given:

a network CIDR : (192.168.0.0/16)

wanted result

192.168.0.0/17, 192.168.128.0/17

Using packages such as the default net package and github.com/brotherpowers/ipsubnet, github.com/seancfoley/ipaddress-go/ipaddr did not get the desired results.

答案1

得分: 2

将网络分成两部分,将前缀的长度增加一即可得到下半部分。要计算第二部分,将网络部分增加一(为简洁起见,省略了错误处理):

package main

import (
	"fmt"
	"math/big"
	"net/netip"
)

func main() {
	p := netip.MustParsePrefix("192.168.0.0/16")
	lo, hi := split(p)
	fmt.Println(lo, hi) // 192.168.0.0/17 192.168.128.0/17
}

func split(p netip.Prefix) (lo, hi netip.Prefix) {
	p = p.Masked()
	lo, _ = p.Addr().Prefix(p.Bits() + 1)

	delta := big.NewInt(1)
	delta.Lsh(delta, uint(lo.Addr().BitLen()-lo.Bits()))

	n := new(big.Int).SetBytes(lo.Addr().AsSlice())
	n.Add(n, delta)

	hiIP, _ := netip.AddrFromSlice(n.Bytes())
	hi = netip.PrefixFrom(hiIP, lo.Bits())

	return lo, hi
}

https://go.dev/play/p/0HLqUK0RmVC

英文:

To split a network in two, increment the length of the prefix by one. That gives you the lower half. To compute the second half, increment the network part by one (error handling omitted for brevity):

package main

import (
	"fmt"
	"math/big"
	"net/netip"
)

func main() {
	p := netip.MustParsePrefix("192.168.0.0/16")
	lo, hi := split(p)
	fmt.Println(lo, hi) // 192.168.0.0/17 192.168.128.0/17
}

func split(p netip.Prefix) (lo, hi netip.Prefix) {
	p = p.Masked()
	lo, _ = p.Addr().Prefix(p.Bits() + 1)

	delta := big.NewInt(1)
	delta.Lsh(delta, uint(lo.Addr().BitLen()-lo.Bits()))

	n := new(big.Int).SetBytes(lo.Addr().AsSlice())
	n.Add(n, delta)

	hiIP, _ := netip.AddrFromSlice(n.Bytes())
	hi = netip.PrefixFrom(hiIP, lo.Bits())

	return lo, hi
}

https://go.dev/play/p/0HLqUK0RmVC

答案2

得分: 0

使用默认的net包和github.com/brotherpowers/ipsubnet、github.com/seancfoley/ipaddress-go/ipaddr等包,并没有得到期望的结果。

以下是使用github.com/seancfoley/ipaddress-go/ipaddr进行操作的方法(请注意,此代码也适用于IPv6和前缀长度的任何更改):

package main

import (
	"fmt"
	"github.com/seancfoley/ipaddress-go/ipaddr"
)

func main() {
	cidr := ipaddr.NewIPAddressString("192.168.0.0/16").GetAddress()
	for i := cidr.AdjustPrefixLen(1).PrefixBlockIterator(); i.HasNext(); {
		fmt.Println(i.Next())
	}
}

输出结果:

192.168.0.0/17
192.168.128.0/17
英文:

"Using packages such as the default net package and github.com/brotherpowers/ipsubnet, github.com/seancfoley/ipaddress-go/ipaddr did not get the desired results."

Here is how to do it with github.com/seancfoley/ipaddress-go/ipaddr (note this code also works with IPv6 and any change in prefix length):

package main

import (
	"fmt"
	"github.com/seancfoley/ipaddress-go/ipaddr"
)

func main() {
	cidr := ipaddr.NewIPAddressString("192.168.0.0/16").GetAddress()
	for i := cidr.AdjustPrefixLen(1).PrefixBlockIterator(); i.HasNext(); {
		fmt.Println(i.Next())
	}
}

Output:

192.168.0.0/17
192.168.128.0/17

huangapple
  • 本文由 发表于 2022年7月8日 02:31:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/72902665.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定