Elixir 长生不老药:验证特定范围内是否存在IP

Elixir 长生不老药:验证特定范围内是否存在IP,elixir,phoenix-framework,Elixir,Phoenix Framework,需要检查给定IP是否存在于这些多个范围内 Given IP: 49.14.1.2 Ranges: 49.14.0.0 - 49.14.63.255, 106.76.96.0 - 106.76.127.255, and so on 我已尝试将其转换为整数并验证范围。IP本身是否有其他方法可以不转换为整数使用:inet.parse_address/1将地址转换为元组形式,并使用简单的元组比较进行比较 iex(33)> a_ip = :inet.parse_address(a) {:ok, {

需要检查给定IP是否存在于这些多个范围内

Given IP: 49.14.1.2
Ranges: 49.14.0.0 - 49.14.63.255, 106.76.96.0 - 106.76.127.255, and so on

我已尝试将其转换为整数并验证范围。IP本身是否有其他方法可以不转换为整数

使用
:inet.parse_address/1
将地址转换为元组形式,并使用简单的元组比较进行比较

iex(33)> a_ip = :inet.parse_address(a)
{:ok, {49, 14, 1, 2}}
iex(34)> low_ip = :inet.parse_address(low)
{:ok, {49, 14, 0, 0}}
iex(35)> high_ip = :inet.parse_address(high)
{:ok, {49, 14, 63, 255}}
iex(36)> a_ip < low_ip
false
iex(37)> a_ip > low_ip
true
iex(38)> a_ip < high_ip
true
iex(39)> a_ip > high_ip
false
iex(33)>a_ip=:inet.parse_地址(a)
{:好的,{49,14,1,2}
iex(34)>低ip=:inet.parse\u地址(低)
{:好的,{49,14,0,0}
iex(35)>高ip=:inet.parse\u地址(高)
{:好的,{49,14,63,255}
iex(36)>a_-ipa_ip>低_ip
真的
iex(38)>a\U ip<高\U ip
真的
iex(39)>a_ip>高_ip
假的

您可以使用尾部递归函数来处理大型列表,并检查每个列表。大致如下:

# First parameter: ip
# Second parameter the list of ranges in a tuple
# Third parameter the passed list, i.e. the ranges it does match
# It return the list of range(s) that the ip matched.
def ip_in_range(ip, [], match_list) do: match_list
def ip_in_range(ip, [{from_ip, to_ip} | rest], match_list) when ip > from_ip and ip < to_ip do: ip_in_range(ip, rest, [{from_ip, to_ip} | match_list])
def ip_in_range(ip, [{from_ip, to_ip} | rest], match_list) when ip < from_ip or ip > to_ip do: ip_in_range(ip, rest, match_list)
你可以随意塑造它,也就是说,检查它属于多少范围。甚至在第一次范围检查成功时退出。

如果您知道,则可以使用以下方法检查特定IP地址是否在IP范围内:

> cidr = InetCidr.parse("49.14.0.0/16")
{{49, 14, 0, 0}, {49, 14, 255, 255}, 16}

> address = InetCidr.parse_address!("49.14.1.2") 
{49, 14, 1, 2}

> InetCidr.contains?(cidr, address)
true

您的IP地址和IP范围的原始格式是什么?它将是字符串格式。您可以在这里添加您尝试过的内容吗?谢谢,是否有任何优化的方法来检查每个范围中给定的IP存在,因为几乎有100个IP范围软件比较字符串不适合您的需要,例如
“25.12.14.10”<“25.12.5.10”。
对于字符串比较是正确的,而对于IP地址比较显然是错误的。因此,元组表示法更好地满足您的需要,您可以使用范围表示法作为
{IpMin,IpMax}
,其中
IpMin
IpMax
都是4元素元组:
{XX,YY,ZZ TT}
谢谢@Pascal,我错过了这些例子。我会相应地更新答案。@petspandaD如果你使用元组表示,检查应该很便宜,因为你只需要将ip地址与每个范围的两个边界进行比较。如果你想进一步加快速度,你必须找到一个更合适的数据结构,类似于index.Thanks.目前正在寻找检查IP范围
(给定IP>=:inet.parse\u address(low1)和&给定IP=:inet.parse\u address(low2)和&给定IP=:inet.parse\u address(low3)和&给定IP)的优化方法
> cidr = InetCidr.parse("49.14.0.0/16")
{{49, 14, 0, 0}, {49, 14, 255, 255}, 16}

> address = InetCidr.parse_address!("49.14.1.2") 
{49, 14, 1, 2}

> InetCidr.contains?(cidr, address)
true