使用Golang计算网络IP地址的CIDR

Golang实现CIDR网络IP操作
这篇博客详细介绍了如何使用Golang进行CIDR网络IP地址的处理,包括理解CIDR概念,通过IP和掩码获取起止IP,计算地址范围内主机数量,以及获取CIDR的掩码信息。

CIDR详解

参考link: https://blog.youkuaiyun.com/han156/article/details/77817031

通过ip/mask获取起止ip

func getIpSegRange(userSegIp, offset uint8) (int, int) {
	var ipSegMax uint8 = 255
	netSegIp := ipSegMax << offset
	segMinIp := netSegIp & userSegIp
	segMaxIp := userSegIp&(255<<offset) | ^(255 << offset)
	return int(segMinIp), int(segMaxIp)
}

func getIpSeg1Range(ipSegs []string, maskLen int) (int, int) {
	if maskLen > 8 {
		segIp, _ := strconv.Atoi(ipSegs[0])
		return segIp, segIp
	}
	ipSeg, _ := strconv.Atoi(ipSegs[0])
	return getIpSegRange(uint8(ipSeg), uint8(8-maskLen))
}

func getIpSeg2Range(ipSegs []string, maskLen int) (int, int) {
	if maskLen > 16 {
		segIp, _ := strconv.Atoi(ipSegs[1])
		return segIp, segIp
	}
	ipSeg, _ := strconv.Atoi(ipSegs[1])
	return getIpSegRange(uint8(ipSeg), uint8(16-maskLen))
}

func getIpSeg3Range(ipSegs []string, maskLen int) (int, int) {
	if maskLen > 24 {
		segIp, _ := strconv.Atoi(ipSegs[2])
		return segIp, segIp
	}
	ipSeg, _ := strconv.Atoi(ipSegs[2])
	return getIpSegRange(uint8(ipSeg), uint8(24-maskLen))
}
func getIpSeg4Range(ipSegs []string, maskLen int) (int, int) {
	ipSeg, _ := strconv.Atoi(ipSegs[3])
	segMinIp, SegMaxIp := getIpSegRange(uint8(ipSeg), uint8(32-maskLen))
	return segMinIp, SegMaxIp
}

func GetCidrIpRange(cidr string) (string, string) {
	ip := strings.Split(cidr, "/")[0]
	ipSegs := strings.Split(ip, ".")
	maskLen, _ := strconv.Atoi(strings.Split(cidr, "/")[1])
	seg1MinIp, seg1MaxIp := getIpSeg1Range(ipSegs, maskLen)
	seg2MinIp, seg2MaxIp := getIpSeg2Range(ipSegs, maskLen)
	seg3MinIp, seg3MaxIp := getIpSeg3Range(ipSegs, maskLen)
	seg4MinIp, seg4MaxIp := getIpSeg4Range(ipSegs, maskLen)
	return strconv.Itoa(seg1MinIp) + "." + strconv.Itoa(seg2MinIp) + "." +
			strconv.Itoa(seg3MinIp) + "." + strconv.Itoa(seg4MinIp),
		strconv.Itoa(seg1MaxIp) + "." + strconv.Itoa(seg2MaxIp) + "." +
			strconv.Itoa(seg3MaxIp) + "." + strconv.Itoa(seg4MaxIp)
}

获取CIDR地址范围内可拥有的主机数量 

func GetCidrHostNum(maskLen int) uint {
	cidrIpNum := uint(0)
	var i uint = uint(32 - maskLen - 1)
	for ; i >= 1; i-- {
		cidrIpNum += 1 << i
	}
	return cidrIpNum
}

获取Cidr的掩码

func getCidrIpMask(maskLen int) string {
	// ^uint32(0)二进制为32个比特1,通过向左位移,得到CIDR掩码的二进制
	cidrMask := ^uint32(0) << uint(32 - maskLen)
	fmt.Println(fmt.Sprintf("%b \n", cidrMask))
	//计算CIDR掩码的四个片段,将想要得到的片段移动到内存最低8位后,将其强转为8位整型,从而得到
	cidrMaskSeg1 := uint8(cidrMask >> 24)
	cidrMaskSeg2 := uint8(cidrMask >> 16)
	cidrMaskSeg3 := uint8(cidrMask >> 8)
	cidrMaskSeg4 := uint8(cidrMask & uint32(255))

	return fmt.Sprint(cidrMaskSeg1) + "." + fmt.Sprint(cidrMaskSeg2) + "." + fmt.Sprint(cidrMaskSeg3) + "." + fmt.Sprint(cidrMaskSeg4)
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值