首页 新闻 会员 周边 捐助

.NET 中如何用 C# 高效地判断私网 IP 地址

0
悬赏园豆:80 [已解决问题] 解决于 2025-07-12 14:23

如何判断当前 IP 地址是否是私网 IP?既要判断 IPv4 又要判断 IPv6

IPv4:

  • 10.0.0.0/8
  • 172.16.0.0/12
  • 192.168.0.0/16

IPv6:

  • fc00::/7(或者ff00::/8

IPv4-mapped IPv6

  • 比如 ::ffff:192.0.2.128
dudu的主页 dudu | 高人七级 | 园豆:24883
提问于:2025-06-13 17:11

go 的一个实现 https://github.com/9glt/go-private-ip

dudu 3个月前

typescript 的一个实现

dudu 3个月前
< >
分享
最佳答案
0

在nuget上用这个类库,可以完美解决
IPAddressRange

//ipv4
var rangeA = IPAddressRange.Parse("192.168.0.0/255.255.255.0"); //也支持 "192.168.0.0/24"
rangeA.Contains(IPAddress.Parse("192.168.0.34")); // is True.
rangeA.Contains(IPAddress.Parse("192.168.10.1")); // is False.

//ipv6
var rangeC = IPAddressRange.Parse("fe80::/10"); 
rangeC.Contains(IPAddress.Parse("fe80::d503:4ee:3882:c586%3")); // is True.
rangeC.Contains(IPAddress.Parse("::1")); // is False.
收获园豆:50
w0rd | 小虾三级 |园豆:526 | 2025-07-12 11:20
dudu | 园豆:24883 (高人七级) | 2025-07-12 14:24
其他回答(1)
1

基本是这样子.

private static bool IsInSubnet(string ipAddress, string cidr)
{
    var parts = cidr.Split('/');

    var baseAddress = BitConverter.ToInt32(IPAddress.Parse(parts[0]).GetAddressBytes(),);

    var address = BitConverter.ToInt32(IPAddress.Parse(ipAddress).GetAddressBytes(), 0);

    var mask = IPAddress.HostToNetworkOrder(-1 << 32 - int.Parse(parts[1])); 

    return (baseAddress & mask) == (address & mask);
}
收获园豆:30
czd890 | 园豆:14650 (专家六级) | 2025-06-16 14:08

chatgpt 给的, 增加了ipv6支持.

private static bool IsInSubnet(string ipAddress, string cidr)
{
    var parts = cidr.Split('/');
    if (parts.Length != 2)
        throw new ArgumentException("Invalid CIDR notation", nameof(cidr));

    var network = IPAddress.Parse(parts[0]);
    var prefixLength = int.Parse(parts[1]);
    var address = IPAddress.Parse(ipAddress);

    var networkBytes = network.GetAddressBytes();
    var addressBytes = address.GetAddressBytes();

    // Ensure both are same address family (IPv4 vs IPv6)
    if (networkBytes.Length != addressBytes.Length)
        return false;

    int fullBytes = prefixLength / 8;
    int remainingBits = prefixLength % 8;

    // Compare full bytes
    for (int i = 0; i < fullBytes; i++)
    {
        if (networkBytes[i] != addressBytes[i])
            return false;
    }

    // Compare remaining bits (if any)
    if (remainingBits > 0)
    {
        byte mask = (byte)(0xFF << (8 - remainingBits));
        if ((networkBytes[fullBytes] & mask) != (addressBytes[fullBytes] & mask))
            return false;
    }

    return true;
}

支持(0) 反对(0) czd890 | 园豆:14650 (专家六级) | 2025-06-16 14:28
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册