如何从基于多个键的哈希中删除重复项?

时间:2014-07-20 22:30:07

标签: ruby-on-rails ruby ruby-on-rails-3

我有一个查询,它会在24小时内返回所有IPS事件并将其串在一起以显示在我的视图中。我想根据[sig_id,ips_attacker_ip,ips_target]键删除重复项。基本上我想除了从同一主机到一台服务器的相同签名ID之外,除了3000多次尝试之外的所有尝试。

@events = IpsEvent.all(conditions: ['timestamp >= ?', ts]).reverse.uniq
# Start IPS Event txt display
@ips_events = []
@events.each do |events|
  ips_timestamp = events.timestamp
  ips_hostname = get_hostname(events.sid)
  sig_id = get_sig_sid(events.signature)
  sig_name = get_sig_name(events.signature)
  sig_protocol = get_event_protocol(events.sid, events.cid)

  if sig_protocol == 6
    sig_protocol = 'tcp'

  elsif sig_protocol == 17
    sig_protocol = 'udp'

  elsif sig_protocol == 1
    sig_protocol = 'icmp'

  elsif !sig_protocol
    sig_protocol = 'null'

  end

  ips_attacker_ip = get_attacker_ip(events.sid, events.cid).to_s(16).rjust(8,'0').scan(/.{2}/).map(&:hex).join('.')
  if get_event_protocol(events.sid, events.cid) == 6
    ips_attacker_port = get_tcp_sport(events.sid, events.cid)

  elsif get_event_protocol(events.sid, events.cid) == 17
    ips_attacker_port = get_udp_sport(events.sid, events.cid)

  elsif get_event_protocol(events.sid, events.cid) == 1
    'icmp'

  elsif !get_event_protocol(events.sid, events.cid)
    'null'

  end

  ips_target = get_target_ip(events.sid, events.cid).to_s(16).rjust(8,'0').scan(/.{2}/).map(&:hex).join('.')
  if get_event_protocol(events.sid, events.cid) == 6
    @ips_target_port = get_tcp_dport(events.sid, events.cid)

  elsif get_event_protocol(events.sid, events.cid) == 17
    ips_target_port = get_udp_dport(events.sid, events.cid)

  elsif get_event_protocol(events.sid, events.cid) == 1
    'icmp'

  elsif !get_event_protocol(events.sid, events.cid)
    'null'

  end

  @ips_events += [timestamp: ips_timestamp,hostname: ips_hostname,signature_id: sig_id,signature_name: sig_name,
                 protocol: sig_protocol, attacker: ips_attacker_ip,attacker_port: ips_attacker_port,
                 target: ips_target,target_port: ips_target_port]

end
# End IPS Event txt display

以下是我认为的代码。

<table>
      <tr>
        <th>Timestamp</th>
        <th>Sensor Name</th>
        <th>Signature ID</th>
        <th>Signature Name</th>
        <th>Protocol</th>
        <th>Source IP</th>
        <th>Source Port</th>
        <th>Target IP</th>
        <th>Target Port</th>    
      </tr>

      <% @ips_events.each do |event| %>
      <tr>
        <td class='timestamp'><%= event[:timestamp] %></td>
        <td class='sensor_name'><%= event[:hostname] %></td>
        <td class='sig_id'><%= event[:signature_id] %></td>
        <td class='sig_name'><%= event[:signature_name] %></td>
        <td class='sig_protocol'><%= event[:protocol] %></td>
        <td class='src_ip'><%= event[:attacker] %></td>
        <td class='src_port'><%= event[:attacker_port] %></td>
        <td class='tgt_ip'><%= event[:target] %></td>
        <td class='tgt_port'><%= event[:target_port] %></td>
      </tr>
      <% end %>

    </table>

这是返回的哈希之一。

{:TIMESTAMP=>SUN, 20 JUL 2014 21:24:28 UTC +00:00, :HOSTNAME=>"VS-101-Z0:DNA0:DNA1", :SIGNATURE_ID=>10000001, :SIGNATURE_NAME=>"DROP - WP-ADMIN ATTEMPT", :PROTOCOL=>"TCP", :ATTACKER=>"203.195.184.151", :ATTACKER_PORT=>60521, :TARGET=>"172.31.251.13", :TARGET_PORT=>80}

1 个答案:

答案 0 :(得分:0)

这可能是Array#reject!的好地方。给定一个数组,它需要一个块,如果你返回false,它将从数组中删除。

@events.reject! do |event|
  ...do your checking based on the keys here...
end