问题
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.
回答1:
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
回答2:
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.
回答3:
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"))
回答4:
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