You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Golang计算主机IP在CIDR子网中的相对位置

使用Golang计算主机IP在子网中的位置

核心思路

把IPv4地址和子网的网络地址都转换为32位无符号整数,用主机IP的整数减去网络地址的整数,得到的结果就是该IP在子网枚举顺序中的位置(网络地址对应位置0,主机IP的位置即为两者差值)。

实现步骤

  1. 解析IP与子网:用net包的ParseIP和ParseCIDR函数分别解析主机IP字符串和子网CIDR格式字符串。
  2. 合法性校验:检查主机IP是否属于目标子网,若不属于则返回错误;同时确保处理的是IPv4地址。
  3. 转换为整数:将IPv4的4字节大端序数据转换为32位无符号整数。
  4. 计算位置:用主机IP的整数减去子网网络地址的整数,得到最终位置。

完整代码示例

package main

import (
	"encoding/binary"
	"errors"
	"fmt"
	"net"
)

// GetHostPosition 计算主机IP在子网中的位置
func GetHostPosition(ipStr, cidrStr string) (uint32, error) {
	// 解析主机IP
	ip := net.ParseIP(ipStr)
	if ip == nil {
		return 0, errors.New("无效的IP地址")
	}
	// 确保是IPv4地址
	ip4 := ip.To4()
	if ip4 == nil {
		return 0, errors.New("仅支持IPv4地址")
	}

	// 解析子网CIDR
	_, ipNet, err := net.ParseCIDR(cidrStr)
	if err != nil {
		return 0, fmt.Errorf("解析CIDR失败: %w", err)
	}
	// 检查IP是否在子网内
	if !ipNet.Contains(ip) {
		return 0, errors.New("IP地址不在目标子网中")
	}

	// 将IP转换为32位整数
	ipInt := binary.BigEndian.Uint32(ip4)
	// 将子网网络地址转换为32位整数
	netIP4 := ipNet.IP.To4()
	netInt := binary.BigEndian.Uint32(netIP4)

	// 计算位置
	return ipInt - netInt, nil
}

func main() {
	// 示例1
	pos1, err := GetHostPosition("172.16.7.173", "172.16.4.0/22")
	if err != nil {
		fmt.Printf("示例1错误: %v\n", err)
	} else {
		fmt.Printf("示例1主机位置: %d\n", pos1) // 输出941
	}

	// 示例2
	pos2, err := GetHostPosition("192.168.0.10", "192.168.0.0/24")
	if err != nil {
		fmt.Printf("示例2错误: %v\n", err)
	} else {
		fmt.Printf("示例2主机位置: %d\n", pos2) // 输出10
	}
}

测试验证

运行代码后,会输出两个示例的预期结果:

  • 示例1输出941
  • 示例2输出10

内容的提问来源于stack exchange,提问作者vickyvikas7988

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 20:37:35