Ruby:你如何使用.uniq!在一个数组上寻找基于正则表达式.scan的重复项?

时间:2014-04-06 14:28:22

标签: ruby-on-rails ruby

我很难抓住.uniq!方法。我试图在我的视图中删除重复的ips警报。

如果我使用Original Code:中的代码,我会在Index View:中收到来自IPS的所有提醒。 这将显示所有警报,例如;我将收到500个警报,可以根据签名ID(sid),源IP(ip_src)和目标IP(ip_dst)将其压缩为1个警报。如果我只是追加.uniq! (如果那就是它应该如何使用)我没有得到任何不同的结果,我认为它不起作用,因为时间戳和源端口不一样,所以它已经是唯一的。以下是两个示例消息,应该是一个而不是两个。

04/04-16:13:47.451062 [**] [1:10000001:1] <dna0:dna1> drop - WP-Admin attempt [**] [Classification: Web Application Attack] [Priority: 1] {TCP} 10.17.21.37:55749 -> 173.239.96.163:80

04/04-16:13:28.474894 [**] [1:10000001:1] <dna0:dna1> drop - WP-Admin attempt [**] [Classification: Web Application Attack] [Priority: 1] {TCP} 10.17.21.37:55707 -> 173.239.96.163:80

我想使用每条消息的签名ID(sid),源IP(ip_src)和目标IP(ip_dst),并删除重复项。

我使用.scan方法查找签名ID,源IP和目标IP。他们是sid, ip_src, ip_dst。我已经停留在@filtered_snort_detail_query.push(ips_detail).uniq!行,并且我真的不知道如何使用sid, ip_src, ip_dst中的信息让@filtered_snort_detail_query向我的视图传递唯一的警报。

索引视图:

<% if @filtered_snort_detail_query.count > 0 %>
  <table>
      <tr>
        <th>Timestamp</th>
        <th>Tag Info</th>
        <th>Message</th>
      </tr>
      <% @filtered_snort_detail_query.each do |d|
        text_msg = d['_source']['message']
        if d['_source']['message'].nil?
        end
      %>
          <tr>
            <td class='timestamp'><%= d['_source']['@timestamp'].to_time %></td>
            <td class='tags'><%= d['_source']['tags'] %></td>
            <td class='message'><%= text_msg %></td>
          </tr>
      <% end %>

    </table>
<% else %>
    <div> No Results Returned. </div>
<% end %>

原始代码:

if @es_snort_detail_query.count > 0
      @filtered_snort_detail_query = Array.new
      @es_snort_detail_query.each do |ips_detail|
        next if ips_detail['_source']['type'] != 'snort-ips'
        next if ips_detail['_source']['@timestamp'] < @ts
        @filtered_snort_detail_query.push(ips_detail)
      end
 end

修改后的代码:

    if @es_snort_detail_query.count > 0
      sid = Array.new
      ip_src = Array.new
      ip_dst = Array.new
      @filtered_snort_detail_query = Array.new
      @es_snort_detail_query.each do |ips_detail|
        next if ips_detail['_source']['type'] != 'snort-ips'
        next if ips_detail['_source']['@timestamp'] < @ts
        if ips_detail['_source']['message'].nil?
          text_msg = ips_detail['_source']['message']
        else
          text_msg = ips_detail['_source']['message']
        end
        unless text_msg.nil?
          sid_data = text_msg.scan(/\[\d+:\d+:\d+\]/)
          src_ip_data = text_msg.scan(/(?:[0-9]{1,3}\.){3}[0-9]{1,3}/)
          dst_ip_data = text_msg.scan(/(?:[0-9]{1,3}\.){3}[0-9]{1,3}/)
          sid.push(sid_data[0]) unless sid_data[0].nil?
          ip_src.push(src_ip_data[0]) unless src_ip_data[0].nil?
          ip_dst.push(dst_ip_data[1]) unless dst_ip_data[1].nil?

          @filtered_snort_detail_query.push(ips_detail).uniq!
          #[{:unique_ids => sid}, {:unique_ids => ip_src}, {:unique_ids => ip_dst}]
        end
      end
      end

1 个答案:

答案 0 :(得分:1)

您可以将一个块传递给uniq,告诉它您要如何重复删除数组:

@filtered_snort_detail_query = @es_snort_detail_query.reject do |ips_detail|
  ips_detail['_source']['type'] != 'snort-ips' || ips_detail['_source']['@timestamp'] < @ts
end.uniq do |ips_detail|
  if ips_detail['_source']['message'].nil?
    text_msg = ips_detail['_source']['message']
  else
    text_msg = ips_detail['_source']['message']
  end
  unless text_msg.nil?
    sid_data = text_msg.scan(/\[\d+:\d+:\d+\]/)
    src_ip_data = text_msg.scan(/(?:[0-9]{1,3}\.){3}[0-9]{1,3}/)
    dst_ip_data = text_msg.scan(/(?:[0-9]{1,3}\.){3}[0-9]{1,3}/)
    [sid_data, src_ip_data, dst_ip_data]
  end
end