英文:
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/ipsubnet
、github.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
}
答案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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论