how should I correctly store IP address list with addresses which are subnets to make it searchable?
There are two examples:
I have IP address 1.2.3.4 and in my C# List there is 1.2.3.4 entry so here we have no problems.
I have IP address 3.4.5.6 and in my C# List I have subnet 3.4.0.0/24. Here is my problem.
How to store IP subnet in List to cover second example?
Thanks
Don't store it in a list - store it in a structure such as a Dictionary instead, where the key is the IP address, and the value is the subnet address.
Define a class that stores an
IPAddress
and the prefix length:Then override
Equals
andGetHashCode
such that only the firstPrefixLength
bits ofIPAddress.GetAddressBytes()
are taken into consideration (and, of course, the IPAddress type).You can then use this class to store subnet prefixes in a
List<T>
or use them as keys of aDictionary<K,V>
:This works with IPv6 addresses, too.
At the end of this answer you will find a complete implementation of a structure to represent a IPV4 address.
Here is really simple example of usage:-
The value "3.4.0.0/255.255.255.0" is displayed inthe console since 3.4.0.6 is found in the 3.4.0.0/24 subnet. Assuming
list
is full of various subnets andx
could contain any address then this:-will select the most specific subnet for that contains
x
.I could use a binary tree with boolean labels on the nodes. Using the standard notation in which 0 is the left child and 1 the right child, 1.2.3.4 would be stored by putting
true
at00000001000000100000001100000100
(the binary representation of that address) in the tree - and false at all nodes between the root and this. Conversely, 3.4.0.0/16 would be stored with atrue
at0000001100000100
(the first 16 bits of the binary representation of 3.4.0.0).When you are given an address to test, just go down the tree according to the bits of that address : if you reach a node a
true
, the address is in the list. If you reach the end of a branch, the address is not in the list.For instance, if looking up 3.4.123.48, you'd go down 16 levels in the tree before reaching true, meaning that this address is in the list. But looking up 129.199.195.13, you'd know from the first 1 bit in that address that it is not part of the list.
I'm not sure how important it is to you to use the
List
type to store those addresses, so this may not help ; OTOH, once you've implemented a basic binary tree with labels, this should have better asymptotic performance characteristics than a .NetList
.I would prefer to create a specialized structure (class) to store all these information together. Probably in near future you would like to extend it to store ipv6 beside ipv4, and maybe some more data (metric, gateway, etc).