Я хочу проверить, находится ли IP 180.179.77.11 между определенным диапазоном, скажем, 180.179.0.0 - 180.179.255.255.

Я написал функцию, которая будет сравнивать каждый октет IP с остальными.

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")

< Сильный > ВЫВОД :

180 < 180 or 180 > 180
False
179 < 179 or 179 > 179
False
77 < 0 or 77 > 255  # 77 > 255 is true
True
False

Однако, это, кажется, не работает должным образом; Похоже, проблема возникла в третьем октете при сравнении 77 с 255.

Я поместил несколько утверждений для печати, чтобы проиллюстрировать проблемную область.

4
Priyank Chheda 13 Янв 2017 в 08:30

4 ответа

Лучший ответ

Вы сравниваете значения strings (которые сравниваются лексикографически), а не значения int для каждого IP, превращаете их в целые числа со значениями:

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('.')]

Также лучше, если вы не выполняете разделение дважды для каждого ip в mask; разделить перед рукой:

s = mask.split(' - ')
min_ip, max_ip = [[int(i) for i in j.split('.')] for j in s]

Ваш цикл for может быть лучше, если бы вы использовали enumerate с ip:

for ind, val in enumerate(ip):
    if val < min_ip[ind] or val > max_ip[ind]:
        return False
2
Enku 18 Сен 2018 в 16:50

Без петли, надеюсь, это полезно.

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")
0
Jaimin Ajmeri 13 Янв 2017 в 07:20

Что не так в вашем сценарии - вы сравниваете строки, а не числа.

Вы можете попробовать это:

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"))
0
Harsha Biyani 13 Янв 2017 в 06:06

При вызове функции match передаются строки, которые разделяются в соответствии с октетами. Однако, когда сравнения сделаны, сравниваемый октет все еще является строкой. Таким образом, «7»> «2» для третьего октета. Если вы преобразуете каждый октет в целое число как:

if int(ip[i]) < int(min_ip[i]) or int(ip[i]) > int(max_ip[i]):

Вы получите ожидаемый ответ.

1
John F 13 Янв 2017 в 05:42