I want to check if IP 180.179.77.11
lies between a particular range, say 180.179.0.0 - 180.179.255.255
.
I wrote a function which will compare every IP octet with the others.
def match(mask, IP):
min_ip = mask.split(' - ')[0].split('.')
max_ip = mask.split(' - ')[1].split('.')
ip = IP.split('.')
for i in range(4):
print ip[i] + " < " + min_ip[i] + " or " + ip[i] + " > " + max_ip[i]
print ip[i] < min_ip[i] or ip[i] > max_ip[i]
if ip[i] < min_ip[i] or ip[i] > max_ip[i]:
return False
return True
match("180.179.0.0 - 180.179.255.255", "180.179.77.11")
OUTPUT:
180 < 180 or 180 > 180
False
179 < 179 or 179 > 179
False
77 < 0 or 77 > 255 # 77 > 255 is true
True
False
However, it doesn't seem to work properly; It looks like the problem occurred in the 3rd octet while comparing 77
with 255
.
I have put some print statements to illustrate the problem area.
You are comparing strings values (which compare lexicographically) and not the int
values for every IP, make them into ints with comprehensions:
min_ip = [int(i) for i in mask.split(' - ')[0].split('.')]
max_ip = [int(i) for i in mask.split(' - ')[1].split('.')]
ip = [int(i) for i in IP.split('.')]
It's also best if you don't perform the split twice for every ip in mask
; split before hand:
s = mask.split(' - ')
min_ip, max_ip = [[int(i) for i in j.split('.')] for j in s]
Your for
loop could arguably be better if you used enumerate
with ip
:
for ind, val in enumerate(ip):
if val < min_ip[ind] or val > max_ip[ind]:
return False
When you call the match function strings are passed in which are split according to the octets. However, when the comparisons are made the octet being compared is still a string. Thus '7' > '2' for the third octet. If you convert each octet to an integer as:
if int(ip[i]) < int(min_ip[i]) or int(ip[i]) > int(max_ip[i]):
You will get the expected response.
What is wrong in your script is - You are comparing string & not numbers.
You can try this:
def match(mask, IP):
min_ip = mask.split(' - ')[0].split('.')
print min_ip
max_ip = mask.split(' - ')[1].split('.')
print max_ip
ip = IP.split('.')
print ip
for i in range(4):
if int(ip[i]) < int(min_ip[i]) or int(ip[i]) > int(max_ip[i]):
return False
return True
print(match("180.179.0.0 - 180.179.255.255", "180.179.77.11"))
Without loop, hope its useful.
def match(mask, IP):
min_ip = mask.split(' - ')[0].split('.')
max_ip = mask.split(' - ')[1].split('.')
range4 = range(int(min_ip[-2]), int(max_ip[-2]) + 1)
range3 = range(int(min_ip[-1]), int(max_ip[-1]) + 1)
ip = IP.split(".")
if ( (int(ip[-2]) in range3) and (int(ip[-1]) in range4) ):
return True
return False
print match("180.179.0.0 - 180.179.255.255", "180.179.77.11")
来源:https://stackoverflow.com/questions/41627920/checking-if-ip-address-lies-within-a-given-range