2009-06-24 133 views
14

我一直在四處尋找,找到一些CID代碼將CIDR表示法(72.20.10.0/24)中的網絡轉換爲IP地址範圍,但沒有多少運氣。有關於stackoverlow CIDR的一些線程,但似乎沒有任何C#代碼,並涵蓋了我所需要的。所以我決定自己做,並且我不希望代碼依賴於System.Net來進行這個版本的任何轉換。如何將CIDR轉換爲C#中的網絡和IP地址範圍?

也許它可能對某人有幫助。

參考文獻:

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

「Whatmask」 C從http://www.laffeycomputer.com/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; 
} 

隨意提交您的改進。

+0

這對我很有幫助,謝謝。 – 2010-05-14 13:08:31

回答

3

的步驟會是這樣的一個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和
  • ~是按位INVERT。
+0

`mask =〜(0xFFFFFFFF >> maskBits)`當'maskBits`爲32時不會產生正確的值 - 值將是0x0而不是0xFFFFFFFF – 2014-09-05 13:47:56

6

這裏是你如何對你的例子72.20.10.0/24做到這一點,

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

  • 這是0xFFFFFF00

StartIP是 - (Network & Mask);

  • 72.20.10.0 & 0xFFFFFF00

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

  • (72.20.10.0 & 0xFFFFFF00) | 0x000000FF

這將是72.20.10.0 -- 72.20.10.255

17

我推薦使用來自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 

有樂趣。

2

這裏是如何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) 
相關問題