比较数组中的元素

时间:2014-08-26 15:18:36

标签: arrays perl

我正在编写一个脚本,用于识别5秒或更短时间内的登录尝试,搜索强力登录尝试。到目前为止,我已经能够使用以下脚本获取日志时间戳并将其转换为可读且可操作的格式:

#!/usr/bin/perl
use warnings;
use strict;

open my $IN, '<', 'test.txt' or die $!;  # Open the file.
while (<$IN>) {                          # Process it line by line.
    my $timestamp = (split)[1];          # Get the second column.
    $timestamp =~ tr/://d;               # Remove colons.
    print "$timestamp\n";
}

我得到的输出看起来像

102432
102434
104240

我想要做的是比较数组中的数字,看看登录尝试之间是否有5秒或更短的延迟。类似的东西:

if ($timestamp + 5 <= 2nd element in array) {
   print "ahhh brute force"
}

同样的事情一直沿着数组元素一直到最后。

if (2nd element in array + 5 <= 3rd element in array) {
   print "ahh brute force"
}

有人可以指出我正确的方向吗?

输入示例:

2014-08-10      13:20:30        GET     Portal/jsjquery-latest.js  404     -       "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko

1 个答案:

答案 0 :(得分:2)

这会按照你的要求行事。它使用Time::Piece,它是Perl 5版本10以来的核心模块,因此不需要安装。

它使用日志文件中的日期和时间字段来构建Time::Piece个对象,然后可以将这些对象相互减去以计算间隔。

程序需要将日志文件的路径作为命令行上的参数

use strict;
use warnings;
use 5.010;

use Time::Piece;

my $last_login;

while (<>) {
   my @login = split;
   my $login = Time::Piece->strptime("@login[0,1]", '%Y-%m-%d %H:%M:%S');

   if ($last_login) {
      my $interval = $login - $last_login;
      if ($interval <= 5) {
         printf "%s to %s is %d seconds\n", $last_login, $login, $interval;
      }
   }

   $last_login = $login;
}

<强>更新

正如@knarf在评论中所述,可以使用正则表达式和Time::Local模块的timelocal函数来完成此操作。

这是一个使用该技术做类似事情的程序。

use strict;
use warnings;

use Time::Local 'timelocal';

my $last_login;

while (<>) {
   next unless my @login = / (\d\d\d\d)-(\d\d)-(\d\d) \s+ (\d\d):(\d\d):(\d\d) /x;
   $login[0] -= 1900;
   $login[1] -= 1;
   my $login = timelocal reverse @login;

   if ($last_login) {
      my $interval = $login - $last_login;
      if ($interval <= 5) {
         printf "%s to %s is %d seconds\n", map(scalar localtime $_, $last_login, $login), $interval;
      }
   }

   $last_login = $login;
}