如果我有子网掩码,例如255.255.255.0
和IP地址192.168.1.5
,有一种简单的方法可以确定该子网中所有可能的IP地址吗?
在这种情况下:
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
...
...
192.168.1.252
192.168.1.253
192.168.1.254
192.168.1.255
直到现在我发现的所有内容都是重载的.net库。是否有任何本地方法可以使用默认命名空间来解决这个问题?
答案 0 :(得分:8)
编码10分钟,未完全测试:
class IPSegment {
private UInt32 _ip;
private UInt32 _mask;
public IPSegment(string ip, string mask) {
_ip = ip.ParseIp();
_mask = mask.ParseIp();
}
public UInt32 NumberOfHosts {
get { return ~_mask+1; }
}
public UInt32 NetworkAddress {
get { return _ip & _mask; }
}
public UInt32 BroadcastAddress {
get { return NetworkAddress + ~_mask; }
}
public IEnumerable<UInt32> Hosts(){
for (var host = NetworkAddress+1; host < BroadcastAddress; host++) {
yield return host;
}
}
}
public static class IpHelpers {
public static string ToIpString(this UInt32 value) {
var bitmask = 0xff000000;
var parts = new string[4];
for (var i = 0; i < 4; i++) {
var masked = (value & bitmask) >> ((3-i)*8);
bitmask >>= 8;
parts[i] = masked.ToString(CultureInfo.InvariantCulture);
}
return String.Join(".", parts);
}
public static UInt32 ParseIp(this string ipAddress) {
var splitted = ipAddress.Split('.');
UInt32 ip = 0;
for (var i = 0; i < 4; i++) {
ip = (ip << 8) + UInt32.Parse(splitted[i]);
}
return ip;
}
}
用法:
static void Main(string[] args) {
IPSegment ip = new IPSegment("192.168.1.1","255.255.255.248");
Console.WriteLine(ip.NumberOfHosts);
Console.WriteLine(ip.NetworkAddress.ToIpString());
Console.WriteLine(ip.BroadcastAddress.ToIpString());
Console.WriteLine("===");
foreach (var host in ip.Hosts()) {
Console.WriteLine(host.ToIpString());
}
Console.ReadLine();
}
答案 1 :(得分:7)
要确定地址范围,请按以下步骤操作:
1)使用您的子网掩码(此处为255.255.255.0)并将其转换为二进制:
11111111.11111111.11111111.00000000
( 8 + 8 + 8 + 0 = 24 -> So you can write your ip adresse like this : 192.168.1.x/24 because you are in a /24 network)
2)你在/ 24网络中有256-2 = 254个主机可用的ip地址(一个用于网络地址(你的范围内的第一个),另一个用于广播地址(你的最后一个)范围))。
3)要获得您的范围,只需获取您的网络地址(根据您的子网掩码的第一个IP地址)并获得接下来的255个IP地址,您将获得您的范围。
您的网络地址:
在二进制文件中,最后一个八位字节必须为null:
xxxxxxxx.xxxxxxxx.xxxxxxxx.00000000
您的广播地址:
在二进制中,最后一个八位字节必须等于1:
xxxxxxxx.xxxxxxxx.xxxxxxxx.11111111
这里你的ip地址是192.168.1.5。 在二进制文件中我们得到:
11000000.10101000.00000000.00000101
第一个可用的IP地址:192.168.1.1
上次使用的IP地址:192.168.1.254
希望你喜欢阅读不好的英语。 如果您有任何疑问,请告诉我 洛里斯
答案 2 :(得分:0)
是的,将所有内容转换为32位表示(假设为IPv4)。如果你的面具是M而ip是IP,则你的ip范围是(M&amp; IP)+1,(M&amp; IP)+ 2,......,(M&amp; IP)+(~M)-1。在哪里&amp;是按位AND和〜按位不是。
将事物转换为32位表示,ip a.b.c.d中的每个点都是一个8位数字。
答案 3 :(得分:0)
好的电话。不要使用额外的库。这很简单。我就是这样做的:
public static uint[] GetIpRange(string ip, IPAddress subnet)
{
uint ip2 = Utils.IPv4ToUInt(ip);
uint sub = Utils.IPv4ToUInt(subnet);
uint first = ip2 & sub;
uint last = first | (0xffffffff & ~sub);
return new uint[] { first, last };
}
注意:强>
你需要做更多的工作将IP转换为uint和back(应该很容易)。然后,您可以在第一个和最后一个之间使用简单的for循环迭代所有IP。
像这样(未经测试):
byte[] bytes = subnet.GetAddressBytes();
uint sub = (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);
IPAddress ip1 = IPAddress.Parse(ip);
bytes = ip1.GetAddressBytes();
uint ip2 = (uint)((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]);