int 似乎不是使用过的 perl 库中的 int

int 似乎不是使用过的 perl 库中的 int

我的脑海中浮现出一个奇怪的现象。如您所知,处理直接暴露在互联网上的邮件服务器可能是一件非常“快乐”的事情,因为许多人试图闯入它或将其用作中继。我在手动阻止通过防火墙的地址或范围时没有任何问题,尽管这需要一些努力。我不太热衷于使用fail2ban 自动化整个过程;我更想知道“发生了什么事”。

因此,我使用 iptables 和 ip6tables 创建了各种规则,它们的数量几乎达到了稳定水平。尽管如此,为了保持某种组织的外观,我想将被阻止的 V4 IP 和 V4 范围的数量与 V4 地址的总数联系起来。关于后者,我忽略了这样一个事实:有一些不允许的地址,例如未路由的广播地址或私有地址范围。相反,我简单地假设可以有 2^32 个具有四个字节的地址。

从 iptables 的规则中,我使用过滤器(主要是 awk)提取指定的 IP 范围,并获得如下所示的列表:

...
27.72.155.100/32
37.9.0.0/20
37.9.32.0/20
37.9.48.0/21
37.9.64.0/18
37.9.128.0/21
...

因此,地址和掩码中有效位的通常组合。我使用一个处理 STDIN 的小型 Perl 程序来处理这个列表。为了从这样的字符串中确定受影响地址的数量,我使用了 Perl 库“Net::IP”,它提供了方便的处理。例如,在 后$str = "37.9.32.0/20",可以执行$ip = new Net::IP($str); $count = $ip -> size();,并且 $count 现在包含 4096,这是 2^(32-20) 的结果。到目前为止,一切都很好。

当我尝试使用 $count 执行计算时,问题就出现了。对所有数量求和后,我想通过除以 2^32 来确定它们占可能的 IP 总量的百分比。即使对于单个值,问题也很明显:尝试将确定的数量 4096 除以 3 不会产生浮点数“1365.33...”,而只会产生整数值 1365。我尝试在除法之前进行转换获得清晰的格式,但这没有帮助。它可能与 Net::IP 使用的面向对象代码有关。我承认,作为一名前汇编程序员,我并不精通面向对象编程,并且对此很挣扎。可能需要的是一种\$count -> getInt()因为:

我采用了蛮力方法,通过在循环中迭代 IP 数量,减少 Net::IP 的 OOP 结果,实际上获得了所需的浮点数结果。但这确实太粗糙了,完全绕过了Net::IP 的优雅概念。此外,我确信你们当中有专家可以向我指出一些能够产生著名的“啊哈效应”的东西,我对此很期待。这是我使用的源代码,在 Perl 中简化为单个 IP 地址/掩码:

#!/usr/bin/perl
use strict;
use Net::IP;
my $count = 0;
my $str = "37.9.32.0/20";
my $ip = new Net::IP($str) or die (Net::IP::Error());
my $count = $ip -> size();

print "this is the result of 4096/3\t\t\t: ", 4096 / 3, "\n";
print "this is count\t\t\t\t\t: ", $count, "\n";
print "and this is the result of \$count / 3\t\t: ", $count / 3, "\n";
print "and this is the result of int(\$count) / 3\t: ", int($count) / 3, "\n";

my $countW = 0;
while ($count > 0) {
        $count--;
        $countW++;
}
print "and now comes the result of \$countW / 3\t\t: ", $countW / 3, "\n";

这里产生的输出:

this is the result of 4096/3                    : 1365.33333333333
this is count                                   : 4096
and this is the result of $count / 3            : 1365
and this is the result of int($count) / 3       : 1365
and now comes the result of $countW / 3         : 1365.33333333333

答案1

您对面向对象代码的猜测是正确的。易于验证blessedfrom标量::Util:

use Scalar::Util qw{ blessed };
...
warn blessed($count);  # Math::BigInt at script.pl line XX.

这可能是因为该模块的作者担心该数字可能会比正常整数大得多。

数学::BigInt用于该类的文档。例如,您可以使用该numify方法来取回纯数字。

my $count = $ip->size->numify;

相关内容