CIDR ip to range
将CIDR类型ip转换为range
ipv6 转换
package main
import (
"fmt"
"net"
)
// ipv6Cidr2Range 将带掩码的ipv6转换成[[]byte startIp, []byte endIp]形式
func ipv6Cidr2Range(ipv6Cidr string) (net.IP, net.IP, error) {
_, ipnet, err := net.ParseCIDR(ipv6Cidr)
if err != nil {
return nil, nil, err
}
start := ipnet.IP.Mask(ipnet.Mask).To16()
end := make(net.IP, len(start))
copy(end, start)
// maskSize 网络位长度
maskSize, _ := ipnet.Mask.Size()
// maskSize向上取整后第一个byte开始全部取0xff
for index := (maskSize + 7) >> 3; index < 16; index++ {
end[index] = 0xff
}
// 对于maskSize长度%8不为0的,即末尾不满足1byte部分需要额外处理——末尾8-(maskSize%8)bit全取1,前maskSize%8位取start中的值
if maskSize % 8 != 0 {
end[((maskSize + 7) >> 3) - 1] |= (1 << uint(8 - maskSize % 8)) - 1
}
return start, end, nil
}
func main() {
tests := [][3]string{
{"2001:db8:abcd:0012::0/0", "::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"},
{"2001:db8:abcd:0012::0/64", "2001:db8:abcd:12::", "2001:db8:abcd:12:ffff:ffff:ffff:ffff"},
{"f000::000f/2", "c000::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"},
{"c000::000f/1", "8000::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"},
{"c000::000f/3", "c000::", "dfff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"},
{"c000::000f/4", "c000::", "cfff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"},
{"d000::000f/16", "d000::", "d000:ffff:ffff:ffff:ffff:ffff:ffff:ffff"},
{"d000:8000::000f/17", "d000:8000::", "d000:ffff:ffff:ffff:ffff:ffff:ffff:ffff"},
{"d000:7000::000f/17", "d000::", "d000:7fff:ffff:ffff:ffff:ffff:ffff:ffff"},
{"d000:7000::000f/18", "d000:4000::", "d000:7fff:ffff:ffff:ffff:ffff:ffff:ffff"},
{"d000:7000::000f/19", "d000:6000::", "d000:7fff:ffff:ffff:ffff:ffff:ffff:ffff"},
{"d800:7000::000f/7", "d800::", "d9ff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"},
// 注意:xxx:000f:xxx 这种会被转换成 xxx:f:xxx
{"d800:7000::000f/128", "d800:7000::f", "d800:7000::f"},
{"d800:7000::000f/127", "d800:7000::e", "d800:7000::f"},
{"d800:7000::000f/125", "d800:7000::8", "d800:7000::f"},
{"d800:000f::000f/32", "d800:f::", "d800:f:ffff:ffff:ffff:ffff:ffff:ffff"},
}
for _, test := range tests {
start, end, err := ipv6Cidr2Range(test[0])
if err != nil {
fmt.Printf("error: %+v\n", err)
}
if start == nil || start.String() != test[1] {
fmt.Printf("error, cur start ipv6 is %s, expect start ipv6 is %s\n", start, test[1])
}
if end == nil || end.String() != test[2] {
fmt.Printf("error, cur start ipv6 is %s, expect start ipv6 is %s\n", end, test[2])
}
}
}
ipv4 转换
// Ip2long 将ip转换成unit32格式
func Ip2long(ipStr string) uint32 {
ip := net.ParseIP(ipStr)
if ip == nil {
return 0
}
ip = ip.To4()
return binary.BigEndian.Uint32(ip)
}
// Ip2range 将带掩码的ip转换成[uint32 startIp, uint32 endIp]形式
func Ip2range(ipWithMast, ReqId string) ([]uint32, error) {
vipSegs := strings.Split(ipWithMast, "/")
ip := vipSegs[0]
var startIp uint32
var endIp uint32
if len(vipSegs) > 1 {
mask, err := strconv.Atoi(vipSegs[1])
if err != nil {
err := log.Logger.Error("[ReqId: %s], mask type conversion failed", ReqId)
return nil, err
}
startIp = Ip2long(ip) & (((1 << uint32(mask)) - 1) << uint32(32-mask))
endIp = Ip2long(ip) | ((1 << uint32(32-mask)) - 1)
} else {
startIp = Ip2long(ip)
endIp = Ip2long(ip)
}
rangIp := []uint32{
startIp,
endIp,
}
return rangIp, nil
}