2017-10-24 1 views
0

IP 주소가 CIDR 표기 IP 범위 목록에 속하는지 확인하는 빠른 방법을 찾고 있습니다.IP 목록이 IP 범위 목록 (CIDR 표기법)에 속하는지 확인하는 빠른 방법

from netaddr import IPNetwork, IPAddress 

    for CIDR in CIDRLIST: 
     if IPAddress(row[0]) in IPNetwork(CIDR): 
      print('success') 

그러나이 솔루션은 너무 느린 내 문제입니다 (800 IP가 CIDR의 범위 및 500.000 IP의 adresses) : 내가 사용 netaddr 예전처럼 예를 본 적이있다.

이렇게 빨리 수행 할 수있는 방법은 무엇입니까? 내가 pytries 사용에 대해 읽었지만, 이것이 해결책이라고 확신하지는 않습니다.

+0

은 루프 대신 목록 인식을 사용하여 성능이 향상되는지 확인합니다. – utengr

+0

어떤 종류의 성능 으로든 "Van Em Boas Tree"를 파이썬으로 구현할 수 있을지 궁금합니다. – Surt

+0

나는 똑같은 문제가있다. 그 대답은 블록 목록을 트리로 전처리 한 다음 트리를 검색한다는 것이다. 이 자료를 공부 한 지 40 년이되었는데 Knuth Volume 3과 상담해야합니다. 고맙게도 IT 부서의 일부 사항은 변경되지 않습니다! 블록에서 가능한 모든 IP에 대한 키가있는 트리를 빌드해야하므로 vEB 트리가 잘 작동한다고 생각하지 않습니다. (내가 Wikipedia 기사를 올바르게 이해했다고 가정). –

답변

1

Patricia/Radix tree/tries가 답으로 보입니다. 라우팅 테이블을 찾는 알고리즘을 검색하여 찾았습니다.

파이썬 구현 here이 있습니다.

조금 나중에 : 지금이이 루비에서 잘 작동 :

 
require 'rpatricia' 
require 'uoainfoblox' 

ib = UoAIinfoblox.new ({'user' => 'xxxxx', 'password' => 'yyyy', 'host' => 'ipam.auckland.ac.nz'}) 

pt = Patricia.new 

ib.get_networks('*roaming_network=true').each do |net, info | 
    pt.add(net) 
end 

puts "'130.216.66.65 #{ pt.include?('130.216.66.65')}" 
puts "130.216.5.128 #{pt.include?('130.216.5.128') }" 

인포 블록은 IP 관리 시스템이며 UoAInfoblox가 자신의 웹 API의 래퍼입니다. 그래서 여기서 로밍 네트워크 목록을 patricia 트리에 추가 한 다음 두 IP 주소 (상태를 알고 있음)를 확인합니다.

편집 : 저는 방금 파이썬을 사용하는 친구로부터 우리 CS 부서의 네트워킹을 가르쳐주었습니다. 그는 그의 연구 스크립트에서 파이썬 기수 모듈을 사용했습니다. 나는 그가 CAIDA에 대한/darkenet으로부터 매우 많은 양의 데이터를 처리하고 있었다는 것을 안다.