我使用Maxmind的地理位置表(特别是城市/国家/地区级别),其中一个表格具有以下结构:
我将服务用户的IP存储在另一个表中;我创建了latitude
和longitude
列,并希望将这些IP的适用纬度和经度存储在users表中(在IP的相应行中)。
可以看出,MaxMind表中的IP以CIDR格式存储,这意味着无法直接检查IP是否符合CIDR给出的IP范围
是否可以仅使用MySQL语句将常规IP与CIDR格式匹配?
我试过了,但是却找到了以下内容:
将users
表中的IP与MaxMind表中的CIDR表示法相匹配需要一段时间,我使用标准的C#CLI程序来处理批处理,我承认我可以做这样:
答案 0 :(得分:0)
如果它有帮助,我前段时间写了这个类来检查IP地址是否在一个范围内。您只需要在CIDR字符串中拆分网络和掩码,解析它们并将它们传递给构造函数。然后,您只需使用ContainsIP()
查看该IP地址是否属于该网络。它可能使用另一个接受CIDR字符串的构造函数来处理拆分/解析。
public class IPNetwork
{
private readonly IPAddress _networkMask;
private readonly int _networkMaskLength;
private readonly uint _networkMaskValue;
public IPNetwork(IPAddress networkMask, int networkMaskLength)
{
if (networkMask.AddressFamily != AddressFamily.InterNetwork)
throw new InvalidOperationException("Only IPv4 networks are supported.");
_networkMask = networkMask;
_networkMaskLength = networkMaskLength;
_networkMaskValue = GetMaskedAddress(networkMask);
}
public bool ContainsIP(IPAddress ipAddress)
{
return GetMaskedAddress(ipAddress) == _networkMaskValue;
}
private uint GetMaskedAddress(IPAddress ipAddress)
{
byte[] bytes = ipAddress.GetAddressBytes();
int addressLength = bytes.Length * 8;
uint addressValue = BytesToValue(bytes);
uint maskedAddress = 0;
for (int i = addressLength - _networkMaskLength; i < addressLength; ++i)
maskedAddress |= addressValue & (1U << i);
return maskedAddress;
}
private uint BytesToValue(byte[] bytes)
{
uint value = 0;
for (int i = 0; i < bytes.Length; ++i)
value |= (uint)(bytes[bytes.Length - i - 1] << (i * 8));
return value;
}
}