Как конвертировать CIDR в сеть и диапазон IP-адресов в С#?
Я довольно много искал, чтобы найти код С# для преобразования сети в нотации CIDR (72.20.10.0/24) в диапазон IP-адресов без большой удачи. Есть несколько потоков о CIDR на stackoverlow, но ни один из них не имеет кода на С# и не охватывает именно то, что мне нужно. Поэтому я решил приготовить его сам, и я не хотел, чтобы код полагался на System.Net для любых преобразований в этой версии.
Возможно, это может помочь кому-то.
Ссылки:
Каков наилучший способ конвертировать из сетевого бита в сетевую маску?
"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;
}
Не стесняйтесь представить свои улучшения.
Ответы
Ответ 1
Я рекомендую использовать класс IPNetwork С# из 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);
Он выйдет
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
Вот как вы это делаете для своего примера 72.20.10.0/24
,
Пусть Network
be 72.20.10.0
Mask
есть ~((1 << (32-24)) - 1)
//или
Mask
~(0xFFFFFFFF >> 24)
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
.
Ответ 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
Где
-
<<
- побитовый сдвиг влево (без опрокидывания)
-
&
побитовое И,
-
|
побитовое ИЛИ, и
-
~
- побитовое значение INVERT.
Ответ 4
Здесь, как преобразовать нотацию 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, который я собрал, который будет вычислять низкий и высокий диапазоны IP от адреса CIDR. Это беспорядочно, и мне пришлось работающие с 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)