github.com/TeaOSLab/EdgeNode@v1.3.8/internal/iplibrary/action_utils.go (about) 1 package iplibrary 2 3 import ( 4 "fmt" 5 "log" 6 "math" 7 "strconv" 8 "strings" 9 ) 10 11 // Convert IPv4 range into CIDR 12 // 来自:https://gist.github.com/P-A-R-U-S/a090dd90c5104ce85a29c32669dac107 13 func iPv4RangeToCIDRRange(ipStart string, ipEnd string) (cidrs []string, err error) { 14 15 cidr2mask := []uint32{ 16 0x00000000, 0x80000000, 0xC0000000, 17 0xE0000000, 0xF0000000, 0xF8000000, 18 0xFC000000, 0xFE000000, 0xFF000000, 19 0xFF800000, 0xFFC00000, 0xFFE00000, 20 0xFFF00000, 0xFFF80000, 0xFFFC0000, 21 0xFFFE0000, 0xFFFF0000, 0xFFFF8000, 22 0xFFFFC000, 0xFFFFE000, 0xFFFFF000, 23 0xFFFFF800, 0xFFFFFC00, 0xFFFFFE00, 24 0xFFFFFF00, 0xFFFFFF80, 0xFFFFFFC0, 25 0xFFFFFFE0, 0xFFFFFFF0, 0xFFFFFFF8, 26 0xFFFFFFFC, 0xFFFFFFFE, 0xFFFFFFFF, 27 } 28 29 ipStartUint32 := iPv4ToUint32(ipStart) 30 ipEndUint32 := iPv4ToUint32(ipEnd) 31 32 if ipStartUint32 > ipEndUint32 { 33 log.Fatalf("start IP:%s must be less than end IP:%s", ipStart, ipEnd) 34 } 35 36 for ipEndUint32 >= ipStartUint32 { 37 maxSize := 32 38 for maxSize > 0 { 39 40 maskedBase := ipStartUint32 & cidr2mask[maxSize-1] 41 42 if maskedBase != ipStartUint32 { 43 break 44 } 45 maxSize-- 46 47 } 48 49 x := math.Log(float64(ipEndUint32-ipStartUint32+1)) / math.Log(2) 50 maxDiff := 32 - int(math.Floor(x)) 51 if maxSize < maxDiff { 52 maxSize = maxDiff 53 } 54 55 cidrs = append(cidrs, uInt32ToIPv4(ipStartUint32)+"/"+strconv.Itoa(maxSize)) 56 57 ipStartUint32 += uint32(math.Exp2(float64(32 - maxSize))) 58 } 59 60 return cidrs, err 61 } 62 63 //Convert IPv4 to uint32 64 func iPv4ToUint32(iPv4 string) uint32 { 65 66 ipOctets := [4]uint64{} 67 68 for i, v := range strings.SplitN(iPv4, ".", 4) { 69 ipOctets[i], _ = strconv.ParseUint(v, 10, 32) 70 } 71 72 result := (ipOctets[0] << 24) | (ipOctets[1] << 16) | (ipOctets[2] << 8) | ipOctets[3] 73 74 return uint32(result) 75 } 76 77 //Convert uint32 to IP 78 func uInt32ToIPv4(iPuInt32 uint32) (iP string) { 79 iP = fmt.Sprintf("%d.%d.%d.%d", 80 iPuInt32>>24, 81 (iPuInt32&0x00FFFFFF)>>16, 82 (iPuInt32&0x0000FFFF)>>8, 83 iPuInt32&0x000000FF) 84 return iP 85 }