IPAddress Range¶
IPAddressRange
is a very basic implementation of an AbstractIPAddressRange used to represent an inclusive range of arbitrary IP Addresses of the same address family. It isn’t restricted to a CIDR representation like a Subnet is, allowing for non-power of two range sizes.
The IPAddressRange
class extends AbstractIPAddressRange and implements IIPAddressRange, IEquatable<IPAddressRange>
, IComparable<IPAddressRange>
, IFormattable
, IEnumerable<IPAddress>
, and ISerializable
.
Creation¶
constructor IPAddress head
, IPAddress tail
¶
To standard way of creating an IPAddressRange
is to construct it via a IPAddress head
and IPAddress tail
. This will construct an IPAddressRange
that would inclusively start with the provided head
and end with tail
.
Addresses MUST be the same address family (either InterNetwork
or InterNetworkV6
).
public IPAddressRange(IPAddress head, IPAddress tail)
constructor IPAddress address
¶
On the rare occasion it may be desirable to make a IPAddressRange
comprised of a single IPAddress
. This too is possible with the following constructor.
public IPAddressRange(IPAddress address)
Static Functionality¶
TryCollapseAll¶
TryCollapseAll
attempts to or collapse the given input of IEnumerable<IPAddressRange> ranges
into as few ranges as possible thus minifying the number or ranges supporting the same data.
Ranges may be collapsed if, and only if, they either overlap, or touch each other and they share the same AddressFamily
.
The function call will return true
if it could collapse two or more ranges. Regardless of if a collapse was possible the out value for result
will be comprised of an IEnumerable<IPAddressRange>
of the calculated ranges.
public static bool TryCollapseAll(IEnumerable<IPAddressRange> ranges, out IEnumerable<IPAddressRange> result)
The following example shows that the three touching ranges of 192.168.1.0 - 192.168.1.5
, 192.168.1.6 - 192.168.1.7
, and 192.168.1.8 - 192.168.1.20
were collapsed into the new IPAddressRange
of 192.168.1.0 - 192.168.1.20
.
[Fact]
public void TryCollapseAll_Consecutive_Example()
{
// Arrange
var ranges = new[]
{
new IPAddressRange(IPAddress.Parse("192.168.1.0"), IPAddress.Parse("192.168.1.5")),
new IPAddressRange(IPAddress.Parse("192.168.1.6"), IPAddress.Parse("192.168.1.7")),
new IPAddressRange(IPAddress.Parse("192.168.1.8"), IPAddress.Parse("192.168.1.20"))
};
// Act
var success = IPAddressRange.TryCollapseAll(ranges, out var results);
var resultList = results?.ToList();
// Assert
Assert.True(success);
Assert.NotNull(results);
Assert.Single(resultList);
var result = resultList.Single();
Assert.Equal(IPAddress.Parse("192.168.1.0"), result.Head);
Assert.Equal(IPAddress.Parse("192.168.1.20"), result.Tail);
}
TryExcludeAll¶
TryExcludeAll
is a tricky beast, but if you’re willing to take the time to tame it’ll not only respect you, but it may also take care of you in very specific cases. The method takes a IPAddressRange initialRange
and with that it attempts to systematically remove each of the sub ranges defined within IEnumerable<IPAddressRange> excludedRanges
. On success, the operation returns true
and will out an IEnumerable<IPAddressRange> result
which is comprised of a distinct remaining ranges after excludedRanges
have been carved out.
public static bool TryExcludeAll(IPAddressRange initialRange, IEnumerable<IPAddressRange> excludedRanges, out IEnumerable<IPAddressRange> result)
TryMerge¶
TryMerge
will take the input of IPAddressRange left
and IPAddressRange right
, and if the two ranges touch or overlap, regardless of order, it will return true
and out IPAddressRange mergedRange
comprised of the now combined ranges sourcing its head
from the lowest valued address of the two inputs and its tail
from the highest valued address of the two.
public static bool TryMerge(IPAddressRange left, IPAddressRange right, out IPAddressRange mergedRange)