Найти - Пользователи
Полная версия: Вхождение ip в заданный дипазон ip-адресов
Начало » Python для экспертов » Вхождение ip в заданный дипазон ip-адресов
1
Igorek
Здравствуйте
Как это сделать вхождение ip в заданные диапазоны ip-адресов подскажите пожалуйста.

необходимо что-то вроде
87.240.0.0/16 - 87.240.9.193 входит
10.0.0.0/24 - 192.168.1.1 не входит
ну и далее
bialix
в простом случае разбить ip-адрес по точкам на список элементов (или сразу задавать диапазон в видед списка элементов) и сравнить каждый элемент на вхождение в определенный диапазон.

т.е.


allowed_range = [, , , range(0,16+1)]
x = ‘87.240.9.193’.split('.')
for i in xrange(4):
allowed = allowed_range
element = x
if not element in allowed:
print ‘Not inside range!’
break
else:
print ‘Inside range’


а как вы диапазоны задаете?
tabajara
allowed_range = ((87, 87), (240, 240), (0, 10), (0,16)) # (min , max)
my_ip = '87.240.9.14'
func = lambda ip, all_range: \
       all(map(lambda (a,b): a[0] <= b <= a[1] , \
           zip(all_range, \
           map(lambda x: int(x), ip.split('.')))))
print func(my_ip, allowed_range)
Андрей Светлов
Я использовал IPLib пару лет назад.
Выдирал его из какого-то клона BitTorrent
Наверняка есть версия и посвежее

Блин, что-то аттач не цепляется



“”“
Library for working with IP addresses
Mainly - check for internet/intranet networks
”“”
__revision__ = “$Revision: 1.5 $”

__all__ =

from bisect import bisect, insort

hexbinmap = {
‘0’: ‘0000’,
‘1’: ‘0001’,
‘2’: ‘0010’,
‘3’: ‘0011’,
‘4’: ‘0100’,
‘5’: ‘0101’,
‘6’: ‘0110’,
‘7’: ‘0111’,
‘8’: ‘1000’,
‘9’: ‘1001’,
‘a’: ‘1010’,
‘b’: ‘1011’,
‘c’: ‘1100’,
‘d’: ‘1101’,
‘e’: ‘1110’,
‘f’: ‘1111’,
‘x’: ‘0000’,
}

chrbinmap = {}
def _make_chrbinmap():
“”“Internal”“”
for j in xrange(256):
res =
k = j
for _ in xrange(8):
if k & 0x80:
res.append('1')
else:
res.append('0')
k <<= 1
chrbinmap = ‘'.join(res)
_make_chrbinmap()

def to_bitfield_ipv4(ipaddr):
“”“convert ipv4 address to bitfield”“”
ipaddr = ipaddr.split(’.')
if len(ipaddr) != 4:
raise ValueError, “bad address”
res =
for i in ipaddr:
res.append(chrbinmap)
return ‘'.join(res)

def to_bitfield_ipv6(ipaddr):
“”“convert ipv6 address to bitfield”“”
res = ’'
doublecolon = False

if ipaddr == ‘':
raise ValueError, “bad address”
if ipaddr == ’::': # boundary handling
ipaddr = ''
elif ipaddr == ‘::’:
ipaddr = ipaddr
elif ipaddr == ‘:’:
raise ValueError, “bad address”
elif ipaddr == ‘::’:
ipaddr = ipaddr
elif ipaddr == ‘:’:
raise ValueError, “bad address”
for part in ipaddr.split(':'):
if part == ‘': # double-colon
if doublecolon:
raise ValueError, “bad address”
doublecolon = True
res += ’:'
continue
if part.find('.') >= 0: # IPv4
part = to_bitfield_ipv4(part)
res += part + ‘0’*(32-len(part))
continue
part = ('x'*(4-len(part))) + part
res += ''.join([hexbinmap for i in part])
if doublecolon:
pos = res.find(':')
res = res+('0'*(129-len(res)))+res
if len(res) != 128: # always check size
raise ValueError, “bad address”
return res

ipv4addrmask = to_bitfield_ipv6('::ffff:0:0')

class IPList(object):
“”“IP list class ”“”
def __init__(self):
“”“Constructor”“”
self.__ipv4list =
self.__ipv6list =

def __nonzero__(self):
“”“test for non zero”“”
return bool(self.__ipv4list or self.__ipv6list)

def append(self, ipaddr, depth = 256):
“”“append address to list”“”
if ipaddr.find(':') < 0: # IPv4
insort(self.__ipv4list, to_bitfield_ipv4(ipaddr))
else:
res = to_bitfield_ipv6(ipaddr)
if res.startswith(ipv4addrmask):
insort(self.__ipv4list, res)
else:
insort(self.__ipv6list, res)

def includes(self, ipaddr):
“”“test for ipaddr in self”“”
if not (self.__ipv4list or self.__ipv6list):
return False
if ipaddr.find(':') < 0: # IPv4
res = to_bitfield_ipv4(ipaddr)
else:
res = to_bitfield_ipv6(ipaddr)
if res.startswith(ipv4addrmask):
res = res
if len(res) > 32:
iplist = self.__ipv6list
else:
iplist = self.__ipv4list
for ipmap in iplist:
if res.startswith(ipmap):
return True
if ipmap > res:
return False
return False

def set_intranet_addresses(self):
“”“appends to self intranet address ranges”“”
self.append('127.0.0.1', 8)
self.append('10.0.0.0', 8)
self.append('172.16.0.0', 12)
self.append('192.168.0.0', 16)
self.append('169.254.0.0', 16)
self.append('::1')
self.append('fe80::', 16)
self.append('fec0::', 16)

def set_ipv4_addresses(self):
“”“appends to self ipv4 range addresses”“”
self.append('::ffff:0:0', 96)

def ipv6_to_ipv4(ipaddr):
“”“convert ipv6 address to ipv4”“”
ipaddr = to_bitfield_ipv6(ipaddr)
if not ipaddr.startswith(ipv4addrmask):
raise ValueError, “not convertible to IPv4”
ipaddr = ipaddr
ret = ''
for i in range(4):
ret += str(int(ipaddr, 2))
if i < 3:
ret += ‘.’
ipaddr = ipaddr
return ret

def to_ipv4(ipaddr):
“”“simular to ipv6_to_ipv4 but checks for ipaddr is valid ipv4”“”
if is_ipv4(ipaddr):
_valid_ipv4(ipaddr)
return ipaddr
return ipv6_to_ipv4(ipaddr)

def is_ipv4(ipaddr):
“”“simple test for ipv4 address”“”
return ipaddr.find(':') < 0

def _valid_ipv4(ipaddr):
“”“Internal”“”
ipaddr = ipaddr.split('.')
if len(ipaddr) != 4:
raise ValueError
for i in ipaddr:
chr(int(i))

def is_valid_ip(ipaddr):
“”“test ipaddr is mailformed”“”
try:
if is_ipv4(ipaddr):
_valid_ipv4(ipaddr)
return True
to_bitfield_ipv6(ipaddr)
return True
except ValueError:
return False

def is_local_ip(ipaddr):
“”“test ipaddr for local range”“”
iplist = IPList()
iplist.set_intranet_addresses()
return iplist.includes(ipaddr)

redixin

#!/usr/bin/python

# usage in_range(ipaddress, net, mask)

from socket import inet_aton

def apply_mask(addr, mask):
ret = ''
for i in range(0,4):
ret = ret + chr(ord(addr) & ord(mask))
return ret


def in_range (ip, net, mask):
ipnet = apply_mask(inet_aton(ip), inet_aton(mask))
return(ipnet == inet_aton(net))

print in_range('10.10.10.1', ‘10.10.10.0’, ‘255.255.255.0’)
Cyxapeff
Довольно давно искал решение такой задачи, в результате получилось:

    def convert_mask(self, string):
""" Преобразует строку в вид сеть-маска, то есть можно задавать диапозоны как со слешам, так и через дефис """
net,mask=re.split("/", string)
if re.search("\.",mask)==None:
i=1
a=""
while i*8<int(mask):
if i!=1:
a+="."
a+="255"
i+=1
x=0
b=""
i-=1
while x<int(mask)-i*8:
b+="1"
x+=1
while x<8:
b+="0"
x+=1
a+="."+str(int(b,2))
i+=2
while i<=4:
if a[-1:]: a+="."
a+="0"
i+=1
mask=str(a)
#print net+"/"+mask
return (net,mask)

def in_net(ip,net,mask):
ip=map(int,re.split("\.", ip))
net=map(int,re.split("\.", net))
mask=map(int,re.split("\.", mask))
i=0
while i<4:
if ip[i]&mask[i]!=net[i]:
return False
i+=1
return True
Вот такая штукенция используется и работает прямо в данный момент. :)
nerezus
Фигасебекода!
Эм, а перевести в int и просто наложить маску?
pythonwin
Фигасебекода!
Эм, а перевести в int и просто наложить маску?
пример сможешь показать?
Андрей Светлов
Да…
Примеров было более чем достаточно. А уметь читать сорцы в Питоне ой как нужно.
Иначе - Ява или Шарп, у них с документацией получше. И все-равно не до конца помогает :)
Igorek
Все решилось прозаичнее, использовал по совету Андрея IPlib 1.0
http://erlug.linux.it/~da/soft/iplib/
все решается в три строки

import iplib

cidr = iplib.CIDR('10.0.0.0/8')
ip = ‘10.2.0.1’

if cidr.is_valid_ip(ip):
print ip
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB