检查一个IP地址是否在一个网段中

 

 

package main

import (
    "fmt"
    "net"
    //"strconv"
    //"strings"
)

// IPRangeCheckerBitwise 使用位运算的 IP 范围检查器
type IPRangeCheckerBitwise struct {
    network     *net.IPNet
    //networkAddr uint32
    //mask        uint32
    startIP     net.IP
    endIP       net.IP
}

// NewIPRangeCheckerBitwise 创建位运算检查器
func NewIPRangeCheckerBitwise(networkCIDR, startIP, endIP string) (*IPRangeCheckerBitwise, error) {
    checker := &IPRangeCheckerBitwise{}
    
    // 解析网络 CIDR
    _, network, err := net.ParseCIDR(networkCIDR)
    if err != nil {
        return nil, err
    }
    checker.network = network
    // 计算网络地址和掩码的整数形式
    //checker.networkAddr = ipToUint32(network.IP.To4())
    //checker.mask = ipToUint32(net.IP(network.Mask).To4())
    
    // 解析起始和结束 IP
    start := net.ParseIP(startIP)
    end := net.ParseIP(endIP)
    if start == nil {
        return nil, fmt.Errorf("无效的 IP 地址: %s", startIP)
    }
    if end == nil {
        return nil, fmt.Errorf("无效的 IP 地址: %s", endIP)
    }
    
    start = start.To4()
    end = end.To4()
    if start == nil {
        return nil, fmt.Errorf("无效的起始 IP: %s", startIP)
    }
    if end == nil {
        return nil, fmt.Errorf("无效的结束 IP: %s", endIP)
    }

    if !network.Contains(start) {
        return nil, fmt.Errorf("startIP(%s) not in: %s", startIP, networkCIDR)
    }
    if !network.Contains(end) {
        return nil, fmt.Errorf("endIP(%s) not in: %s", endIP, networkCIDR)
    }

    if ipToUint32(start) > ipToUint32(end) {
        return nil, fmt.Errorf("startIP(%s) should <= endIP(%s)", startIP, endIP)
    }
    
    checker.startIP = start
    checker.endIP = end
    
    return checker, nil
}

// ipToUint32 将 IP 转换为 32 位无符号整数
func ipToUint32(ip net.IP) uint32 {
    ip = ip.To4()
    return uint32(ip[0])<<24 | uint32(ip[1])<<16 | uint32(ip[2])<<8 | uint32(ip[3])
}

// Check 检查 IP 是否在范围内
func (c *IPRangeCheckerBitwise) Check(ipStr string) (bool, error) {
    ip := net.ParseIP(ipStr)
    if ip == nil {
        return false, fmt.Errorf("无效的 IP 地址: %s", ipStr)
    }
    
    ip = ip.To4()
    if ip == nil {
        return false, fmt.Errorf("需要 IPv4 地址: %s", ipStr)
    }
    
    // 检查是否在指定网络中
    if !c.network.Contains(ip) {
        return false, nil
    }

    // 检查是否在指定范围内
    return ipToUint32(ip) >= ipToUint32(c.startIP) && ipToUint32(ip) <= ipToUint32(c.endIP), nil
}

func main() {
    // 创建针对特定范围的检查器
    checker, err := NewIPRangeCheckerBitwise("192.168.30.1/24", "192.168.30.1", "192.168.30.255")
    if err != nil {
        fmt.Printf("NewIPRangeCheckerBitwise Failed: %v\n", err)
        return
    }
    testIPs := []string{
        "192.168.29.255",
        "192.168.30.1",
        "192.168.30.2",
        "192.168.30.255",
        "192.168.31.0",
        "192.168.31.250",
        "192.168.31.251",
        "192.168.32.0",
    }
    
    fmt.Println("位运算检查器:")
    for _, ip := range testIPs {
        result, err := checker.Check(ip)
        if err != nil {
            fmt.Printf("IP: %-15s 错误: %v\n", ip, err)
        } else {
            fmt.Printf("IP: %-15s 在范围内: %t\n", ip, result)
        }
    }
    
    // 验证位运算结果
    //fmt.Println("\n位运算验证:")
    //fmt.Printf("网络地址: 192.168.30.0 = 0x%X\n", checker.networkAddr)
    //fmt.Printf("掩码: 255.255.254.0 = 0x%X\n", checker.mask)
    //fmt.Printf("起始IP: 192.168.30.2 = 0x%X\n", checker.startIP)
    //fmt.Printf("结束IP: 192.168.31.250 = 0x%X\n", checker.endIP)
}

 

posted @ 2025-09-30 17:46  LiuYanYGZ  阅读(9)  评论(0)    收藏  举报