如何在 C# 中将 CIDR 转换为网络和 IP 地址范围?

发布于 2024-07-25 13:06:47 字数 1918 浏览 8 评论 0 原文

我一直在寻找一些 C# 代码来将 CIDR 表示法 (72.20.10.0/24) 的网络转换为 IP 地址范围,但运气不佳。 stackoverlow 上有一些关于 CIDR 的线程,但似乎没有一个有任何 C# 代码并且完全涵盖了我所需要的内容。 所以我决定自己做,并且我不希望代码在此版本中依赖 System.Net 进行任何转换。

也许这对某人有帮助。

参考文献:

从网络转换的最佳方式是什么位计数到网络掩码?

“Whatmask”来自 http://www.laffeycomputer.com/ 的 C 代码Whatmask.html

用法:

uint startIP, endIP;  
Network2IpRange("72.20.10.0/24", out startIP, out endIP); 

该代码假定所有内容都是 32 位。

static void Network2IpRange(string sNetwork, out uint startIP, out uint endIP)
{           
    uint ip,        /* ip address */
        mask,       /* subnet mask */               
        broadcast,  /* Broadcast address */
        network;    /* Network address */

    int bits;               

    string[] elements = sNetwork.Split(new Char[] { '/' });         

    ip = IP2Int(elements[0]);
    bits = Convert.ToInt32(elements[1]);

    mask = ~(0xffffffff >> bits);

    network = ip & mask;
    broadcast = network + ~mask;

    usableIps = (bits >30)?0:(broadcast - network - 1); 

    if (usableIps <= 0)
    {
        startIP = endIP = 0; 
    }
    else
    {
        startIP = network + 1;              
        endIP = broadcast - 1;
    }
}

public static uint IP2Int(string IPNumber)
{
    uint ip = 0;
    string[] elements = IPNumber.Split(new Char[] { '.' });
    if (elements.Length==4)
    {
        ip  = Convert.ToUInt32(elements[0])<<24;
        ip += Convert.ToUInt32(elements[1])<<16;
        ip += Convert.ToUInt32(elements[2])<<8;
        ip += Convert.ToUInt32(elements[3]);
    }
    return ip;
}

请随时提交您的改进。

I have been looking around quite a bit to find some C# code to convert a network in CIDR notation (72.20.10.0/24) to an IP address range, without much luck. There are some threads about CIDR on stackoverlow, but none seems to have any C# code and cover exactly what I need. So I decided to cook it myself, and I did not want the code to rely on System.Net for any conversions in this version.

Perhaps it may be of help to someone.

References:

What's the best way to convert from network bitcount to netmask?

"Whatmask" C code from http://www.laffeycomputer.com/whatmask.html

Usage:

uint startIP, endIP;  
Network2IpRange("72.20.10.0/24", out startIP, out endIP); 

The code assumes 32 bits for everything.

static void Network2IpRange(string sNetwork, out uint startIP, out uint endIP)
{           
    uint ip,        /* ip address */
        mask,       /* subnet mask */               
        broadcast,  /* Broadcast address */
        network;    /* Network address */

    int bits;               

    string[] elements = sNetwork.Split(new Char[] { '/' });         

    ip = IP2Int(elements[0]);
    bits = Convert.ToInt32(elements[1]);

    mask = ~(0xffffffff >> bits);

    network = ip & mask;
    broadcast = network + ~mask;

    usableIps = (bits >30)?0:(broadcast - network - 1); 

    if (usableIps <= 0)
    {
        startIP = endIP = 0; 
    }
    else
    {
        startIP = network + 1;              
        endIP = broadcast - 1;
    }
}

public static uint IP2Int(string IPNumber)
{
    uint ip = 0;
    string[] elements = IPNumber.Split(new Char[] { '.' });
    if (elements.Length==4)
    {
        ip  = Convert.ToUInt32(elements[0])<<24;
        ip += Convert.ToUInt32(elements[1])<<16;
        ip += Convert.ToUInt32(elements[2])<<8;
        ip += Convert.ToUInt32(elements[3]);
    }
    return ip;
}

Feel free to submit your improvements.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

月下伊人醉 2024-08-01 13:06:54

以下是如何将 CIDR 表示法转换为 T-SQL 中的范围,来自我的博客文章

首先在 SQL Server 中预先创建此函数(来自
http://www.stardeveloper.com)。

CREATE FUNCTION [dbo].[ConvertIPToLong](@IP varchar(15))
RETURNS bigint
AS
BEGIN
    DECLARE @Long bigint
    SET @Long = CONVERT(bigint, PARSENAME(@IP, 4)) * 256 * 256 * 256 +
        CONVERT(bigint, PARSENAME(@IP, 3)) * 256 * 256 +
        CONVERT(bigint, PARSENAME(@IP, 2)) * 256 +
        CONVERT(bigint, PARSENAME(@IP, 1))

    RETURN (@Long)
END

这是我整理的 T-SQL 代码示例,用于计算
CIDR 地址的低 IP 范围和高 IP 范围。 很乱,我不得不这么做
解决 T-SQL 缺乏移位运算符的问题。

Declare @CidrIP varchar(50)
Set @CidrIP = '10.100.60.55/28'

Select dbo.[ConvertIPToLong](left(@CidrIP, patindex('%/%' , @CidrIP) - 1)) & (cast(4294967295 as bigint) ^ (Power(2, 32 - Cast(substring(@CidrIP, patindex('%/%' , @CidrIP) + 1, 2) as int)) - 1)) as LowRange,
       dbo.[ConvertIPToLong](left(@CidrIP, patindex('%/%' , @CidrIP) - 1)) & (cast(4294967295 as bigint) ^ (Power(2, 32 - Cast(substring(@CidrIP, patindex('%/%' , @CidrIP) + 1, 2) as int)) - 1)) + (Power(2, 32 - Cast(substring(@CidrIP, patindex('%/%' , @CidrIP) + 1, 2) as int)) - 1)

Here's how to convert CIDR notation to a range in T-SQL, from my blog post :

First pre-create this function in SQL Server (from
http://www.stardeveloper.com).

CREATE FUNCTION [dbo].[ConvertIPToLong](@IP varchar(15))
RETURNS bigint
AS
BEGIN
    DECLARE @Long bigint
    SET @Long = CONVERT(bigint, PARSENAME(@IP, 4)) * 256 * 256 * 256 +
        CONVERT(bigint, PARSENAME(@IP, 3)) * 256 * 256 +
        CONVERT(bigint, PARSENAME(@IP, 2)) * 256 +
        CONVERT(bigint, PARSENAME(@IP, 1))

    RETURN (@Long)
END

This is a sample of T-SQL code I put together that will calculate the
low and high IP ranges from a CIDR address. It's messy and I had to
work around T-SQL's lack of bit shift operators.

Declare @CidrIP varchar(50)
Set @CidrIP = '10.100.60.55/28'

Select dbo.[ConvertIPToLong](left(@CidrIP, patindex('%/%' , @CidrIP) - 1)) & (cast(4294967295 as bigint) ^ (Power(2, 32 - Cast(substring(@CidrIP, patindex('%/%' , @CidrIP) + 1, 2) as int)) - 1)) as LowRange,
       dbo.[ConvertIPToLong](left(@CidrIP, patindex('%/%' , @CidrIP) - 1)) & (cast(4294967295 as bigint) ^ (Power(2, 32 - Cast(substring(@CidrIP, patindex('%/%' , @CidrIP) + 1, 2) as int)) - 1)) + (Power(2, 32 - Cast(substring(@CidrIP, patindex('%/%' , @CidrIP) + 1, 2) as int)) - 1)
无需解释 2024-08-01 13:06:53

对于network/maskBits,步骤如下,

您可以通过这两种方式之一计算mask

mask = ~((1 << (32 - maskBits)) - 1) // or,
mask = ~(0xFFFFFFFF >> maskBits)

那么范围是,

StartIP = network 
EndIP   = network | ~mask

更准确地说,

StartIP = network & mask
EndIP   = (network & mask) | ~mask

其中,

  • << 是按位左移(无翻转)
  • & 是按位 AND,
  • | 是按位 OR,
  • ~是按位反转。

The steps would go like this for a network/maskBits,

You compute the mask in one of these two ways,

mask = ~((1 << (32 - maskBits)) - 1) // or,
mask = ~(0xFFFFFFFF >> maskBits)

then the range is,

StartIP = network 
EndIP   = network | ~mask

More precisely,

StartIP = network & mask
EndIP   = (network & mask) | ~mask

Where,

  • << is bitwise left shift (without rollover)
  • & is bitwise AND,
  • | is bitwise OR, and
  • ~ is bitwise INVERT.
离去的眼神 2024-08-01 13:06:52

以下是示例 72.20.10.0/24 的操作方法,

Network72.20.10.0
掩码~((1 << (32-24)) - 1) // 或
Mask~(0xFFFFFFFF >> 24)

  • 0xFFFFFF00

StartIP 是 -- (网络和掩码);

  • 这是 72.20.10.0 & 0xFFFFFF00

EndIP 是 -- ((网络和掩码) | ~Mask);

  • 这是 (72.20.10.0 & 0xFFFFFF00) | 0x000000FF

这将是 72.20.10.0 -- 72.20.10.255

Here is how you do it for your example 72.20.10.0/24,

Let Network be 72.20.10.0
Mask is ~((1 << (32-24)) - 1) // or
Mask is ~(0xFFFFFFFF >> 24)

  • which is 0xFFFFFF00

StartIP is -- (Network & Mask);

  • which is 72.20.10.0 & 0xFFFFFF00

EndIP is -- ((Network & Mask) | ~Mask);

  • which is (72.20.10.0 & 0xFFFFFF00) | 0x000000FF

This will be 72.20.10.0 -- 72.20.10.255.

盛装女皇 2024-08-01 13:06:50

我建议使用 Github 中的 C# IPNetwork 类。

string net = "192.168.168.100/24";
IPNetwork ipnetwork = IPNetwork.Parse(net);

Console.WriteLine("Network : {0}", ipnetwork.Network);
Console.WriteLine("Netmask : {0}", ipnetwork.Netmask);
Console.WriteLine("Broadcast : {0}", ipnetwork.Broadcast);
Console.WriteLine("FirstUsable : {0}", ipnetwork.FirstUsable);
Console.WriteLine("LastUsable : {0}", ipnetwork.LastUsable);
Console.WriteLine("Usable : {0}", ipnetwork.Usable);
Console.WriteLine("Cidr : {0}", ipnetwork.Cidr);

它将输出

Network : 192.168.168.0
Netmask : 255.255.255.0
Broadcast : 192.168.168.255
FirstUsable : 192.168.168.1
LastUsable : 192.168.168.254
Usable : 254 
Cidr : 24

玩得开心。

I recommend to use the C# IPNetwork class from Github.

string net = "192.168.168.100/24";
IPNetwork ipnetwork = IPNetwork.Parse(net);

Console.WriteLine("Network : {0}", ipnetwork.Network);
Console.WriteLine("Netmask : {0}", ipnetwork.Netmask);
Console.WriteLine("Broadcast : {0}", ipnetwork.Broadcast);
Console.WriteLine("FirstUsable : {0}", ipnetwork.FirstUsable);
Console.WriteLine("LastUsable : {0}", ipnetwork.LastUsable);
Console.WriteLine("Usable : {0}", ipnetwork.Usable);
Console.WriteLine("Cidr : {0}", ipnetwork.Cidr);

It will ouput

Network : 192.168.168.0
Netmask : 255.255.255.0
Broadcast : 192.168.168.255
FirstUsable : 192.168.168.1
LastUsable : 192.168.168.254
Usable : 254 
Cidr : 24

Have fun.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文