Форум сайта python.su
Здравствуйте
Как это сделать вхождение ip в заданные диапазоны ip-адресов подскажите пожалуйста.
необходимо что-то вроде
87.240.0.0/16 - 87.240.9.193 входит
10.0.0.0/24 - 192.168.1.1 не входит
ну и далее
Офлайн
в простом случае разбить 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’
а как вы диапазоны задаете?
Офлайн
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)
Отредактировано (Май 24, 2007 14:39:09)
Офлайн
Я использовал 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)
Отредактировано (Май 24, 2007 15:53:14)
Офлайн
#!/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’)
Офлайн
Довольно давно искал решение такой задачи, в результате получилось:
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
Офлайн
Фигасебекода!
Эм, а перевести в int и просто наложить маску?
Отредактировано (Май 26, 2007 15:42:40)
Офлайн
Фигасебекода!пример сможешь показать?
Эм, а перевести в int и просто наложить маску?
Офлайн
Да…
Примеров было более чем достаточно. А уметь читать сорцы в Питоне ой как нужно.
Иначе - Ява или Шарп, у них с документацией получше. И все-равно не до конца помогает :)
Офлайн
Все решилось прозаичнее, использовал по совету Андрея 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
Офлайн