我需要使用以下ipaddress“192.168.0.1/20”搜索mysql数据库中的条目
注意:存储的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。*。* 条目存储在字符串中。它有效,但我不确定这是否正确
可以指出问题或更优化的解决方案吗?
答案 0 :(得分: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');