如何在 C# List 中存储 IP 地址列表以使其也可搜索子网?
我应该如何正确存储包含子网地址的 IP 地址列表以使其可搜索?
有两个示例:
我的 IP 地址为 1.2.3.4,并且在我的 C# 列表中存在 1.2.3.4 条目,因此这里没有问题。
我的 IP 地址为 3.4.5.6,在我的 C# 列表中我有子网 3.4.0.0/24。这是我的问题。
如何在列表中存储 IP 子网以覆盖第二个示例?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在本答案的最后,您将找到表示 IPV4 地址的结构的完整实现。
这是非常简单的用法示例:-
值“3.4.0.0/255.255.255.0”显示在控制台中,因为在 3.4.0.0/24 子网中找到了 3.4.0.6。假设
list
充满了各种子网,并且x
可以包含任何地址,那么:-将选择包含
x
的最具体的子网。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
.定义一个存储
IPAddress
和前缀长度的类:然后重写
Equals
和GetHashCode
,这样只有第一个PrefixLength
> IPAddress.GetAddressBytes() 的位被考虑在内(当然还有 IPAddress 类型)。然后,您可以使用此类将子网前缀存储在
List
中,或将它们用作Dictionary
的键:这适用于 IPv6 地址,也。
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.
我更愿意创建一个专门的结构(类)来将所有这些信息存储在一起。
也许在不久的将来,您希望将其扩展为除了 ipv4 之外还存储 ipv6,也许还可以存储更多数据(指标、网关等)。
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).
我可以使用节点上带有布尔标签的二叉树。使用标准表示法,其中 0 是左子节点,1 是右子节点,1.2.3.4 将通过将
true
放置在00000001000000100000001100000100
(该地址的二进制表示形式)来存储在树中 - 在根和此之间的所有节点处为 false。相反,3.4.0.0/16 将使用true
存储在0000001100000100
(3.4.0.0 二进制表示的前 16 位)。当给你一个要测试的地址时,只需根据该地址的位沿着树向下走:如果到达一个
true
节点,则该地址位于列表中。如果您到达分支的末尾,则该地址不在列表中。例如,如果查找 3.4.123.48,则需要在树中向下查找 16 层才能到达 true,这意味着该地址位于列表中。但是查找 129.199.195.13,您可以从该地址的前 1 位知道它不属于列表的一部分。
我不确定使用
List
类型来存储这些地址对您来说有多重要,因此这可能没有帮助; OTOH,一旦您实现了带有标签的基本二叉树,它应该具有比 .NetList
更好的渐近性能特征。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
.不要将其存储在列表中 - 将其存储在字典等结构中,其中键是 IP 地址,值是子网地址。
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.