【问题标题】:how to search for the ip addresses in cidr notation如何以 cidr 表示法搜索 IP 地址
【发布时间】:2016-01-07 08:41:16
【问题描述】:

我需要在mysql数据库中搜索以下ip地址“192.168.0.1/20”的条目

注意:存储的 ip 地址是 varchars(例如 192.168.0.3,192.168.0.4)

Address:   192.168.0.1          11000000.10101000.0000 0000.00000001
Netmask:   255.255.240.0 = 20   11111111.11111111.1111 0000.00000000
Wildcard:  0.0.15.255           00000000.00000000.0000 1111.11111111
=>
Network:   192.168.0.0/20       11000000.10101000.0000 0000.00000000
HostMin:   192.168.0.1          11000000.10101000.0000 0000.00000001
HostMax:   192.168.15.254       11000000.10101000.0000 1111.11111110
Broadcast: 192.168.15.255       11000000.10101000.0000 1111.11111111
Hosts/Net: 4094                  Class C, Private Internet

我的解决方案是从给定的 cidr 表示法中找到网络地址(将 0 替换为“*”)并在数据库中搜索 192.168.*.* 条目,因为它们存储在字符串中。它有效,但我不确定这是否正确

谁能指出问题或比这更优化的解决方案?

【问题讨论】:

  • 您使用 192.168.*.* 的解决方案将不起作用,因为 192.168.0.1/20 的最大主机地址为 192.168.15.254,但您的数据库中可能有地址,例如 192.168.16.1、192.168.16.2等。
  • 谢谢 stanislav(掌心移动)
  • 就我而言,我目前只看到 2 个解决方案:获取所有地址并使用 IN 子句,或者获取最小和最大主机,将它们分成 4 个组,为每个组创建一个正则表达式如果它们不相同,则将 4 个正则表达式组与点一起拆分并尝试使用正则表达式调用查询。但它可能导致不是最佳选择...
  • 这个“SELECT * from address where INET_ATON(ip_address) > {STARTING_IP_ADDRESS} && INET_ATON(ip_address) ultratools.com/tools/netMaskResult?ipAddress=192.168.0.1%2F20+)
  • 好像不错,我对MySQL不是很熟悉,主要是Oracle或者PG,不知道MySQL有这样的功能。但是您是否也不需要制作 INET_ATON({STARTING_IP_ADDRESS}) 并使其也等于?

标签: java mysql network-programming ip-address cidr


【解决方案1】:

如果每个 VARCHAR 字段只有一个 IP 地址,则以下方法有效。

使用网络掩码将 IP 地址与其网络匹配的正确方法是通过INET_ATON()/INET_NTOA()

不过,有几个步骤。首先使用以下将您的长度转换为子网掩码:

SET @l=20;
SELECT INET_NTOA(0xffffffff >> (32-@l) << (32-@l));

这只是为了传达这个想法,为了使它有用,您可以执行以下操作:

SELECT 0xffffffff >> (32-@l) << (32-@l) INTO @mask;


对于地址与您的网络地址的实际匹配,您可以使用带有位运算符的INET_ 函数,例如:

SET @l=20;
SET @nw='192.168.0.0';
SELECT 0xffffffff >> (32-@l) << (32-@l) INTO @mask;
SELECT * FROM yourtable 
 WHERE (INET_ATON(addrfield) & @mask) = INET_ATON(@nw);

当然,您可以将其合并为一条语句,例如:

SELECT * FROM yourtable 
     WHERE (INET_ATON(addrfield) & (0xffffffff >> (32-@l) << (32-@l))) = INET_ATON('192.168.0.0');

【讨论】:

  • 你能看看我的最后一条评论“SELECT * from address where INET_ATON(ip_address) > {STARTING_IP_ADDRESS} && INET_ATON(ip_address)
  • @rockyit86,是的,如果您有第一个和最后一个地址,即该子网的网络和广播地址,则可以使用。
  • 有趣地使用LPAD()RPAD() 构建掩码@vhu。生成掩码的替代方法包括0xffffffff &gt;&gt; @l &lt;&lt; @l~0 &gt;&gt; 32 &amp; ~0 &lt;&lt; @l
  • @Michael-sqlbot,同意这是更好的方法。
  • 如果我做了减法,d'oh。 (32 - @l) 确实如此。 +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-26
  • 1970-01-01
  • 1970-01-01
  • 2017-08-23
  • 2011-10-06
  • 2010-10-02
  • 1970-01-01
相关资源
最近更新 更多