gpt4 book ai didi

mysql - 来自 ip2location 的 IP 数据库并在 Perl 中将 IPV4 转换为 IPV6

转载 作者:行者123 更新时间:2023-11-29 12:31:40 33 4
gpt4 key购买 nike

我正在尝试使用来自 ip2location 的 IP 到国家/地区数据库.

我的问题是,IPV6 数据库文件是否已包含嵌入的 IPV4 地址或者我是否必须同时使用 IPV4 和 IPV6 数据库来覆盖互联网的所有 IP 范围适用于所有版本。

我的意思是,如果我想同时支持 IPV4 和 IPV6,我应该加载这两个数据库文件进入同一个 mysql 表,或者我应该只使用 IPV6。

我正在谈论文件 IP2LOCATION-LITE-DB11.CSV.ZIP 和 IP2LOCATION-LITE-DB11.IPV6.CSV.ZIP

最佳答案

经过两天的搜索和测试,我正在回答我自己的问题。 IPV4 可以嵌入到 IPV6 中,此文件 IP2LOCATION-LITE-DB11.IPV6.CSV.ZIP包含嵌入为 IPV6 的 IPV4,所有 IP 都存储为十进制 (39, 0)。

我在这里使用 IPV4 和 IPV6 这两个版本的 IPV6 数据库文件的技巧是,在搜索数据库时将 IPV4 地址转换为 IPV6,然后转换为整数,然后正常搜索。这样您的应用程序就可以同时支持 IPV4 和 IPV6。

要将 IPV4 转换为 IPV6,这篇 wiki 文章就是答案:

http://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses

IPv4 映射的 IPv6 地址

Hybrid dual-stack IPv6/IPv4 implementations recognize a special class of addresses,
the IPv4-mapped IPv6 addresses. In these addresses, the first 80 bits are zero, the
next 16 bits are one, and the remaining 32 bits are the IPv4 address. One may see these
addresses with the first 96 bits written in the standard IPv6 format, and the
remaining 32 bits written in the customary dot-decimal notation of IPv4. For example,
::ffff:192.0.2.128 represents the IPv4 address 192.0.2.128. A deprecated format for
IPv4-compatible IPv6 addresses was ::192.0.2.128

这篇文章也很好地讨论了这个问题:

IPv6/IPv4 Address Embedding

enter image description here

您需要做的就是在 IP 前面添加 ::ffff:,这样 IP 地址 192.0.2.128 将是 ::ffff:192.0.2.128 作为有效的 IPV6。

下一步是将您的 IP IPV4 或 IPV6 转换为 Decimail (39,0),您现在可以正常搜索数据库。

由于我使用 Perl,这里有一些用于测试和清除的帮助代码。

use Net::IP ':PROC';

# IPV4 address
my $ipaddress = '197.36.107.146';

my $ip = new Net::IP ($ipaddress) or die (Net::IP::Error());
print ("IPV4 : ".$ip->ip()."\n");
print ("IPV4 Integer : ".$ip->intip()."\n");
print ("Version : ".$ip->version()."\n");
print ("Size: ".$ip->size()."\n");
print ("Len : ".$ip->prefixlen()."\n");
print ("Type: ".$ip->iptype()."\n");
print "\n";

# Convert IPV4 to IPV6. Just prepend ipv4 with '::ffff:'
my $ip = new Net::IP ("::ffff:".$ipaddress) or die (Net::IP::Error());
print ("IPV6 : ".$ip->ip()."\n");
print ("IPV6 Integer : ".$ip->intip()."\n");
print ("Version : ".$ip->version()."\n");
print ("Size: ".$ip->size()."\n");
print ("Len : ".$ip->prefixlen()."\n");
print ("Type: ".$ip->iptype()."\n");
print "\n";

# detect the user ip address and convert it

my $user_ip = get_user_ip();
$user_ip ||= $ipaddress; # just for testing on command line
print "Detected User IP address: $user_ip\n";

# if user remote address is IPV4 convert it to IPV6
if ($user_ip =~ /\./) {
# Convert IPV4 to IPV6
$user_ip = Net::IP->new("::ffff:$user_ip");
# Now convert it to Integer
$user_ip = $user_ip->intip();
}
else {
# Already IPV6, just convert to Integer
$user_ip = Net::IP->new($user_ip);
$user_ip = $user_ip->intip();
}

print "User IP address in IPV6 format: $user_ip\n";
#----------------------------------
# Now you can search the geo database with IPV4 and IPV6 stored as decimails
# select * from ip_country where $ipaddress<=ip_to limit 1
#----------------------------------
sub get_user_ip {
foreach (qw(REMOTE_ADDR HTTP_CLIENT_IP HTTP_X_FORWARDED_FOR HTTP_X_FORWARDED HTTP_X_CLUSTER_CLIENT_IP
HTTP_FORWARDED_FOR HTTP_FORWARDED)) {
if ($ENV{$_}) {
return $ENV{$_};
}
}
}

这是此测试代码的输出:

IPV4  : 197.36.107.146
IPV4 Integer : 3307498386
Version : 4
Size: 1
Len : 32
Type: PUBLIC

IPV6 : 0000:0000:0000:0000:0000:ffff:c524:6b92
IPV6 Integer : 281473989241746
Version : 6
Size: 1
Len : 128
Type: IPV4MAP

Detected User IP address: 197.36.107.146
User IP address in IPV6 format: 281473989241746

到目前为止搜索数据库显示一切正常。

关于mysql - 来自 ip2location 的 IP 数据库并在 Perl 中将 IPV4 转换为 IPV6,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27398691/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com