【问题标题】:How to convert CIDR to network and IP address range in C#?如何在 C# 中将 CIDR 转换为网络和 IP 地址范围?
【发布时间】:2010-11-05 11:56:58
【问题描述】:

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

也许它可能对某人有帮助。

参考文献:

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

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

用法:

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;
}

随时提交您的改进。

【问题讨论】:

  • 对我有帮助,谢谢。

标签: c# cidr


【解决方案1】:

network/maskBits 的步骤如下所示,

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

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

那么范围是,

StartIP = network 
EndIP   = network | ~mask

更准确地说,

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

在哪里,

  • &lt;&lt; 是按位左移(不翻转)
  • &amp; 是按位与,
  • | 是按位或,并且
  • ~ 是按位反转。

【讨论】:

  • mask = ~(0xFFFFFFFF &gt;&gt; maskBits) 不会在maskBits 为 32 时产生正确的值 - 该值将是 0x0 而不是 0xFFFFFFFF
  • 实际上我没有让这些方法中的任何一个起作用。 ~(0xFFFFFFFF &gt;&gt; 24) 返回 0.255.255.255 而不是 255.255.255.0。对我有用的是:0xFFFFFFFF &gt;&gt; -24
【解决方案2】:

以下是您的示例72.20.10.0/24

Network72.20.10.0
Mask~((1 &lt;&lt; (32-24)) - 1) // 或
Mask~(0xFFFFFFFF &gt;&gt; 24)

  • 这是0xFFFFFF00

StartIP 是 -- (Network &amp; Mask);

  • 这是72.20.10.0 &amp; 0xFFFFFF00

EndIP 是 -- ((Network &amp; Mask) | ~Mask);

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

这将是72.20.10.0 -- 72.20.10.255

【讨论】:

    【解决方案3】:

    我建议使用来自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
    

    玩得开心。

    【讨论】:

      【解决方案4】:

      以下是如何将 CIDR 表示法转换为 T-SQL 中的范围,from my blog post

      首先在 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 范围。它很乱,我不得不 解决 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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-11-10
        • 2017-04-23
        • 2017-08-23
        • 2016-05-22
        • 1970-01-01
        • 2018-10-27
        • 2012-11-07
        相关资源
        最近更新 更多