我使用geoip数据库,导入ipv4数据库非常容易,CIDR格式转换为范围和范围为整数。
但我无法找到任何可以找到如何存储和搜索IPv6的中心资源。
我尝试将IPv6 CIDR转换为范围,搜索库
使用ipaddr.js
转换"2001:240:1000::/36"
它返回[ { parts: [ 8193, 576, 4096, 0, 0, 0, 0, 0 ] }, 36 ]
,真的无法将其转换为int
位搜索
function ip62long($ipv6){
$ip_n = inet_pton($ipv6);
$bits = 15;
$ipv6long = 0;
while($bits >= 0){
$bin = sprintf("%08b",(ord($ip_n[$bits])));
if($ipv6long){
$ipv6long = $bin . $ipv6long;
}
else{
$ipv6long = $bin;
}
$bits--;
}
return gmp_strval(gmp_init($ipv6long, 2), 10);
}
我正在尝试导入mongodb,
请指导我如何在节点js中存储和搜索ipv6。
答案 0 :(得分:2)
MongoDB没有数据类型,非常适合IPv6地址。整数最多只能达到64位,但IPv6地址为128位。
最好的解决方法可能是将它们存储为字符串。当您不删除省略的零时,IPv6地址按字母顺序排序。这意味着您可以通过给出最小值和最大值来表示范围。 IP范围2001:240:1000::/36
可表示为:
{
from: "20010240100000000000000000000000",
to: "200102401fffffffffffffffffffffff"
}
要查找2001:240:1024::125a:32fd
之类的IP地址范围,您可以执行此查询:
db.ipranges.find({
from: { $lt:"200102401024000000000000125a32fd"},
to: { $gt:"200102401024000000000000125a32fd"}
});
但是,根据您的使用情况,仅存储IP范围的前64位可能就足够了。在IPv6地址中,前64位是网络前缀,后64位是接口标识符。接口标识符是主机的MAC地址或完全随机(具有隐私扩展)。接口标识符和地理位置之间没有关系。这意味着您不会遇到任何超过64位的GeoIP范围。因此,将IPv6范围的前64位存储为整数就足够了。