package cidr import ( "bytes" "fmt" "math" "net" "sort" ) // SuperNetting 合并网段 func SuperNetting(ns []string) (*cidr, error) { num := len(ns) if num < 1 || (num&(num-1)) != 0 { return nil, fmt.Errorf("子网数量必须是2的次方") } mask := "" var cidrs []*cidr for _, n := range ns { // 检查子网CIDR有效性 c, err := ParseCIDR(n) if err != nil { return nil, fmt.Errorf("网段%v格式错误", n) } cidrs = append(cidrs, c) // TODO 暂只考虑相同子网掩码的网段合并 if len(mask) == 0 { mask = c.Mask() } else if c.Mask() != mask { return nil, fmt.Errorf("子网掩码不一致") } } AscSortCIDRs(cidrs) // 检查网段是否连续 var network net.IP for _, c := range cidrs { if len(network) > 0 { if !network.Equal(c.ipNet.IP) { return nil, fmt.Errorf("必须是连续的网段") } } network = net.ParseIP(c.Broadcast()) IncrIP(network) } // 子网掩码左移,得到共同的父网段 c := cidrs[0] ones, bits := c.MaskSize() ones = ones - int(math.Log2(float64(num))) c.ipNet.Mask = net.CIDRMask(ones, bits) c.ipNet.IP.Mask(c.ipNet.Mask) return c, nil } // IncrIP IP地址自增 func IncrIP(ip net.IP) { for i := len(ip) - 1; i >= 0; i-- { ip[i]++ if ip[i] > 0 { break } } } // DecrIP IP地址自减 func DecrIP(ip net.IP) { length := len(ip) for i := length - 1; i >= 0; i-- { ip[length-1]-- if ip[length-1] < 0xFF { break } for j := 1; j < length; j++ { ip[length-j-1]-- if ip[length-j-1] < 0xFF { return } } } } // Compare 比较IP大小 a等于b,返回0; a大于b,返回+1; a小于b,返回-1 func Compare(a, b net.IP) int { return bytes.Compare(a, b) } // AscSortCIDRs 升序 func AscSortCIDRs(cs []*cidr) { sort.Slice(cs, func(i, j int) bool { if n := bytes.Compare(cs[i].ipNet.IP, cs[j].ipNet.IP); n != 0 { return n < 0 } if n := bytes.Compare(cs[i].ipNet.Mask, cs[j].ipNet.Mask); n != 0 { return n < 0 } return false }) } // DescSortCIDRs 降序 func DescSortCIDRs(cs []*cidr) { sort.Slice(cs, func(i, j int) bool { if n := bytes.Compare(cs[i].ipNet.IP, cs[j].ipNet.IP); n != 0 { return n >= 0 } if n := bytes.Compare(cs[i].ipNet.Mask, cs[j].ipNet.Mask); n != 0 { return n >= 0 } return false }) }