43

当 IP 范围写为 aaa.bbb.ccc.ddd/netmask(CIDR 表示法)时,我需要使用 C# 计算此范围内包含的第一个和最后一个 IP 地址。

例子:

输入: 192.168.0.1/25

结果: 192.168.0.1 - 192.168.0.126

4

8 回答 8

65

我的好朋友Alessandro有一篇关于 C# 中的位运算符的好文章,您应该阅读它,以便您知道该怎么做。

这很容易。如果你把给你的IP分解成二进制,网络地址就是所有主机位(子网掩码中的0)都是0的IP地址,最后一个地址,广播地址,是所有主机的地址位为 1。

例如:

ip 192.168.33.72 mask 255.255.255.192

11111111.11111111.11111111.11000000 (subnet mask)
11000000.10101000.00100001.01001000 (ip address)

粗体部分是 HOST 位(其余是网络位)。如果您将 IP 上的所有主机位都设置为 0,您将获得第一个可能的 IP:

11000000.10101000.00100001.01000000 (192.168.33.64)

如果您将所有主机位都设置为 1,那么您将获得最后一个可能的 IP(也就是广播地址):

11000000.10101000.00100001.01111111 (192.168.33.127)

所以对于我的例子:

the network is "192.168.33.64/26":
Network address: 192.168.33.64
First usable: 192.168.33.65 (you can use the network address, but generally this is considered bad practice)
Last useable: 192.168.33.126
Broadcast address: 192.168.33.127
于 2009-09-24T10:23:16.813 回答
29

我将发布代码:

IPAddress ip = new IPAddress(new byte[] { 192, 168, 0, 1 });
int bits = 25;

uint mask = ~(uint.MaxValue >> bits);

// Convert the IP address to bytes.
byte[] ipBytes = ip.GetAddressBytes();

// BitConverter gives bytes in opposite order to GetAddressBytes().
byte[] maskBytes = BitConverter.GetBytes(mask).Reverse().ToArray();

byte[] startIPBytes = new byte[ipBytes.Length];
byte[] endIPBytes = new byte[ipBytes.Length];

// Calculate the bytes of the start and end IP addresses.
for (int i = 0; i < ipBytes.Length; i++)
{
    startIPBytes[i] = (byte)(ipBytes[i] & maskBytes[i]);
    endIPBytes[i] = (byte)(ipBytes[i] | ~maskBytes[i]);
}

// Convert the bytes to IP addresses.
IPAddress startIP = new IPAddress(startIPBytes);
IPAddress endIP = new IPAddress(endIPBytes);
于 2009-09-24T10:34:55.933 回答
8

反转掩码(与一个异或),并将其与 IP。加 1。这将是起始范围。或带掩码的 IP。这将是结束范围。

于 2009-09-24T10:12:51.937 回答
8

我在网络部署位置工作时学到了这个捷径。它对我帮助很大,我想我会与大家分享这个秘密。到目前为止,我还没有找到我所知道的更简单的在线方法。

例如一个网络 192.115.103.64 /27,范围是多少?

只要记住子网掩码是 0, 128, 192, 224, 240, 248, 252, 254, 255

255.255.255.255 11111111.11111111.11111111.11111111 /32

255.255.255.254 11111111.11111111.11111111.11111110 /31

255.255.255.252 11111111.11111111.11111111.11111100 /30

255.255.255.248 11111111.11111111.11111111.11111000 /29

255.255.255.240 11111111.11111111.11111111.11110000 /28

255.255.255.224 11111111.11111111.11111111.11100000 /27

255.255.255.192 11111111.11111111.11111111.11000000 /26

255.255.255.128 11111111.11111111.11111111.10000000 /25

255.255.255.0 11111111.11111111.11111111.00000000 /24

从 /27 我们知道 (11111111.11111111.11111111.11100000)。从左数到最后一个八位字节的第三个数字,等于 255.255.255.224 子网掩码。(不要算 0,0 是 /24)所以 128、192、224..etc

这里的数学进来:

使用子网掩码 - 在这种情况下,之前列出的子网掩码的子网掩码 224-192=32

我们知道 192.115.103.64 是网络:64 + 32 = 96(/27 的下一个网络)

这意味着我们有 .0 .32。64. 96. 128. 160. 192. 224. (不能使用 256,因为它是 0.255)

这是范围 64 - 96。

网络是64。

第一个主机是65。(第一个网络+1)

最后主持人是94。(广播-1)

广播是95。(最后一个网络-1)

于 2011-11-30T18:45:22.323 回答
7

我建议使用 IPNetwork 库https://github.com/lduchosal/ipnetwork。从版本 2 开始,它也支持 IPv4 和 IPv6。

IPv4

  IPNetwork ipnetwork = IPNetwork.Parse("192.168.0.1/25");

  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.0.0
  Netmask : 255.255.255.128
  Broadcast : 192.168.0.127
  FirstUsable : 192.168.0.1
  LastUsable : 192.168.0.126
  Usable : 126
  Cidr : 25

玩得开心 !

于 2015-08-11T09:41:13.700 回答
4

输入:192.168.0.1/25

面具是这部分:/25

要查找网络地址,请执行以下操作:

  • 从 ip 长度 (32 - mask) = 32 - 25 = 7 中减去掩码,然后从右边取出这些位

  • 在给定的 ip 地址192.168.0.1中,即:二进制是: 11111111 11111111 00000000 00000001 现在,从右边的 '0' 中取 7 位 1111111 11111111 00000000 00000000 ,十进制是:( 192.168.0.0这是网络地址)

要找到第一个有效/可用的 IP 地址,请将 +1 添加到网络地址,即:192.168.0.1

查找最后/广播地址的过程与查找网络地址的过程相同,但在这里您必须将(32-mask)位从右到“1”

即:11111111 11111111 00000000 01111111 十进制是192.168.0.127

要找到最后一个有效/可用的 IP 地址,请从广播地址中减去 1,即:192.168.0.126

于 2016-03-05T16:11:57.917 回答
2

我知道这是一个较老的问题,但我在 nuget 上发现了这个漂亮的库,它似乎对我有用:

http://nuget.org/packages/TakeIo.NetworkAddress/

于 2013-06-03T17:46:58.517 回答
2

您可能已经知道这一点,但要检查您是否正确了解这些内容,请查看http://www.subnet-calculator.com/ - 您可以在那里看到这些位如何表示地址的网络和主机部分.

于 2009-09-24T11:03:53.143 回答