Python - поисковый словарь - PullRequest
2 голосов
/ 13 января 2012

Пример данных:

{
    10116079620: {'ip.dst': ['10.1.1.5'], 'ip.src': ['1.2.3.4'], 'category': ['Misc']}, 
    10116882439: {'ip.dst': ['1.2.3.4'], 'ip.src': ['10.1.1.5'], 'category': ['Misc']}, 
    10116080136: {'ip.dst': ['10.10.10.99'], 'ip.src': ['1.2.3.4'], 'category': ['Misc']}, 
    10116884490: {'ip.dst': ['10.10.10.99'], 'ip.src': ['2.3.4.5'], 'alias': ['www.example.com'], 'category': ['Misc']}, 
    10117039635: {'ip.dst': ['2.3.4.5'], 'ip.src': ['10.11.11.50'], 'alias': ['google.com'], 'category': ['Misc']}, 
    10118099993: {'ip.dst': ['1.2.3.4'], 'ip.src': ['10.11.11.49'], 'alias': ['www.google.com'], 'category': ['Misc']},
    10118083243: {'ip.dst': ['10.11.11.49'], 'ip.src': ['4.3.2.1'], 'alias': ['www.google.com'], 'category': ['Misc']}}
}

Цель:

Моя цель - найти в образце словаря значение (IP-адрес), о котором известно, что оно существует, хотя неизвестно, появится ли оно в ip.dst или ip.src. После обнаружения я хочу записать «противоположный» (другой) IP-адрес в новый список ... если искомый адрес был найден в ip.src, я хочу перехватить ip.dst и наоборот.

Найденный адрес может быть найден более одного раза - в результирующем списке не должно быть дубликатов.

При поиске 1.2.3.4 будет зафиксировано следующее:
* 10.1.1.5
* 10.10.10.99
* 10.11.11.49

При поиске 10.10.10.99 будет записано:
* 1.2.3.4
* 2.3.4.5

Это, я уверен, просто, но я застрял в грязных, вложенных петлях и мне нужна краткая процедура, более ясная, чем моя грязь.

Ваша помощь приветствуется.

Спасибо.

Ответы [ 6 ]

5 голосов
/ 13 января 2012

Шаг 1. Инвертировать словарь.

dst= collections.defaultdict( list )
src= collections.defaultdict( list )
for k in original:
    for addr in original[k]['ip.dst']:
        dst[addr].append( k )
    for addr in original[k]['ip.src']:
        src[addr].append( k )

Шаг 2. Не ищите, просто получите значение.

Вы делаете две почти мгновенные проверки на dst[addr] и src[addr], и вы знаете все ключи в исходном словаре, где это произошло.

Инвертирование словаря требует времени.

Создание лучших словарей в первую очередь (т. Е. Проиндексированных по ip.dst и ip.src) экономит затраты на инвертирование уже имеющегося у вас словаря.

2 голосов
/ 13 января 2012

Просто для удовольствия, вот как вы можете сделать это в понимании одной строки!

set([v['ip.dst'][0] for v in my_dict.values() if v['ip.src'] == [search_ip]] + [v['ip.src'][0] for v in my_dict.values() if v['ip.dst'] == [search_ip]])

Выход:

>>>search_ip = '1.2.3.4'
>>>my_dict = {10116079620: {'ip.dst': ['10.1.1.5'], 'ip.src': ['1.2.3.4'], 'category': ['Misc']}, 10116882439: {'ip.dst': ['1.2.3.4'], 'ip.src': ['10.1.1.5'], 'category': ['Misc']}, 10116080136: {'ip.dst': ['10.10.10.99'], 'ip.src': ['1.2.3.4'], 'category': ['Misc']},  10116884490: {'ip.dst': ['10.10.10.99'], 'ip.src': ['2.3.4.5'], 'alias': ['www.example.com'], 'category': ['Misc']},  10117039635: {'ip.dst': ['2.3.4.5'], 'ip.src': ['10.11.11.50'], 'alias': ['google.com'], 'category': ['Misc']},  10118099993: {'ip.dst': ['1.2.3.4'], 'ip.src': ['10.11.11.49'], 'alias': ['www.google.com'], 'category': ['Misc']}, 10118083243: {'ip.dst': ['10.11.11.49'], 'ip.src': ['4.3.2.1'], 'alias': ['www.google.com'], 'category': ['Misc']}}
>>>set([v['ip.dst'][0] for v in my_dict.values() if v['ip.src'] == [search_ip]] + [v['ip.src'][0] for v in my_dict.values() if v['ip.dst'] == [search_ip]])
set(['10.1.1.5', '10.10.10.99', '10.11.11.49'])

>>>search_ip = '10.10.10.99'
>>>set([v['ip.dst'][0] for v in my_dict.values() if v['ip.src'] == [search_ip]] + [v['ip.src'][0] for v in my_dict.values() if v['ip.dst'] == [search_ip]])
set(['1.2.3.4', '2.3.4.5'])
1 голос
/ 13 января 2012

Вот понимание списка, где data - ваш словарь, а ip - то, что вы ищете:

set(ips[ips[0]==ip] for ips in ((v['ip.dst'][0],v['ip.src'][0]) for v in data.itervalues()) if ip in ips)

1 голос
/ 13 января 2012

Я опирался на ответ С. Лотта с некоторыми отличиями.Я использовал наборы для удаления дубликатов и собрал вместе индексы поиска, чтобы лучше соответствовать ответам, которые вы предлагали.

import collections

# data = your example data dictionary

index = collections.defaultdict(set)
for key in data:
    datum = data[key]
    for ip in datum['ip.dst']:
        index[ip].update(datum['ip.src'])
    for ip in datum['ip.src']:
        index[ip].update(datum['ip.dst'])

print index['1.2.3.4']
print index['10.10.10.99']

возвращает:

set(['10.10.10.99', '10.1.1.5', '10.11.11.49'])
set(['1.2.3.4', '2.3.4.5'])
0 голосов
/ 13 января 2012

Без каких-либо библиотек (но решение S.Lott короче, лучше, и мне это очень понравилось, смеется):

x={
    10116079620: {'ip.dst': ['10.1.1.5'], 'ip.src': ['1.2.3.4'], 'category': ['Misc']}, 
    10116882439: {'ip.dst': ['1.2.3.4'], 'ip.src': ['10.1.1.5'], 'category': ['Misc']}, 
    10116080136: {'ip.dst': ['10.10.10.99'], 'ip.src': ['1.2.3.4'], 'category': ['Misc']}, 
    10116884490: {'ip.dst': ['10.10.10.99'], 'ip.src': ['2.3.4.5'], 'alias': ['www.example.com'], 'category': ['Misc']}, 
    10117039635: {'ip.dst': ['2.3.4.5'], 'ip.src': ['10.11.11.50'], 'alias': ['google.com'], 'category': ['Misc']}, 
    10118099993: {'ip.dst': ['1.2.3.4'], 'ip.src': ['10.11.11.49'], 'alias': ['www.google.com'], 'category': ['Misc']},
    10118083243: {'ip.dst': ['10.11.11.49'], 'ip.src': ['4.3.2.1'], 'alias': ['www.google.com'], 'category': ['Misc']}
}

y=[(i['ip.dst'],i['ip.src']) for i in x.values()]

a,b=zip(*y)

#Looking for
lf=['1.2.3.4']
ips=[]


i=0
for ipsrc in a:
    if ipsrc == lf:
        ips.append(b[i])
    i+=1

i=0
for ipdst in b:
    if ipdst == lf:
        ips.append(a[i])
    i+=1

ips=set(ips)
print(ips)
0 голосов
/ 13 января 2012
from functools import partial

def search_row(results, ip, row):
    if row['ip.dst'][0] == ip:
        results.add(row['ip.src'][0])
    if row['ip.src'][0] == ip:
        results.add(row['ip.dst'][0])

def search(ip, data):
    results = set()
    aggregator = partial(search_row, results, ip)
    map(aggregator, data.values())    
    return results

print search('1.2.3.4', data)

print search('10.10.10.99', data)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...