Как я могу проверить, находится ли IP в сети в Python?

Вам необходимо загрузить ключ учетной записи службы (файл JSON), а затем установить переменную среды GOOGLE_APPLICATION_CREDENTIALS, чтобы она указывала на этот файл на вашем устройстве.

credential_path = "D:\****.json"
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = credential_path

Не забудьте импортировать библиотеку os по import os

. См. https://cloud.google.com/firestore/docs/quickstart-servers для более подробная информация.

88
задан Mark Amery 10 February 2019 в 22:30
поделиться

5 ответов

В этой статье показано, что вы можете сделать это с модулями socket и struct без особых дополнительных усилий. Я добавил немного к статье следующее:

import socket,struct

def makeMask(n):
    "return a mask of n bits as a long integer"
    return (2L<<n-1) - 1

def dottedQuadToNum(ip):
    "convert decimal dotted quad string to long integer"
    return struct.unpack('L',socket.inet_aton(ip))[0]

def networkMask(ip,bits):
    "Convert a network address to a long integer" 
    return dottedQuadToNum(ip) & makeMask(bits)

def addressInNetwork(ip,net):
   "Is an address in a network"
   return ip & net == net

address = dottedQuadToNum("192.168.1.1")
networka = networkMask("10.0.0.0",24)
networkb = networkMask("192.168.0.0",24)
print (address,networka,networkb)
print addressInNetwork(address,networka)
print addressInNetwork(address,networkb)

Это выводит:

False
True

Если вы просто хотите одну функцию, которая принимает строки, она будет выглядеть следующим образом:

import socket,struct

def addressInNetwork(ip,net):
   "Is an address in a network"
   ipaddr = struct.unpack('L',socket.inet_aton(ip))[0]
   netaddr,bits = net.split('/')
   netmask = struct.unpack('L',socket.inet_aton(netaddr))[0] & ((2L<<int(bits)-1) - 1)
   return ipaddr & netmask == netmask
34
ответ дан 24 November 2019 в 07:22
поделиться

Мне нравится использовать для этого netaddr :

from netaddr import CIDR, IP

if IP("192.168.0.1") in CIDR("192.168.0.0/24"):
    print "Yay!"

Как указано в комментариях arno_v, новая версия netaddr делает это следующим образом:

from netaddr import IPNetwork, IPAddress
if IPAddress("192.168.0.1") in IPNetwork("192.168.0.0/24"):
    print "Yay!"
146
ответ дан 24 November 2019 в 07:22
поделиться

Я ничего не знаю в стандартной библиотеке, но PySubnetTree - это библиотека Python, которая выполняет сопоставление подсетей.

1
ответ дан 24 November 2019 в 07:22
поделиться

Использование ipaddress ( в stdlib начиная с 3.3 , в PyPi для 2.6 / 2.7 ):

>>> import ipaddress
>>> ipaddress.ip_address('192.168.0.1') in ipaddress.ip_network('192.168.0.0/24')
True

Если вы Если вы хотите таким образом оценить лот IP-адресов, вы, вероятно, захотите заранее рассчитать сетевую маску, например

n = ipaddress.ip_network('192.0.0.0/16')
netw = int(n.network_address)
mask = int(n.netmask)

Затем для каждого адреса вычислить двоичное представление с одним из

a = int(ipaddress.ip_address('192.0.43.10'))
a = struct.unpack('!I', socket.inet_pton(socket.AF_INET, '192.0.43.10'))[0]
a = struct.unpack('!I', socket.inet_aton('192.0.43.10'))[0]  # IPv4 only

Наконец, вы можете просто проверить:

in_network = (a & mask) == netw
113
ответ дан 24 November 2019 в 07:22
поделиться

Спасибо за ваш скрипт!
Я довольно долго работал над ним, чтобы все работало... Поэтому я делюсь им здесь

  • Использование класса netaddr в 10 раз медленнее, чем использование двоичного преобразования, поэтому если вы хотите использовать его на большом списке IP, вы должны рассмотреть возможность не использовать класс netaddr
  • функция makeMask не работает! Работает только для /8,/16,/24
    Ex:

    bits = "21" ; socket.inet_ntoa(struct.pack('=L',(2L << int(bits)-1) - 1))
    '255.255.31.0', тогда как должно быть 255.255.248.0

    Поэтому я использовал другую функцию calcDottedNetmask(mask) из http://code.activestate.com/recipes/576483-convert-subnetmask-from-cidr-notation-to-dotdecima/
    Ex:


#!/usr/bin/python
>>> calcDottedNetmask(21)
>>> '255.255.248.0'
  • Другой проблемой является процесс определения принадлежности IP к сети! Основная операция должна заключаться в сравнении (ipaddr & netmask) и (network & netmask).
    Ex: на данный момент функция неправильная

#!/usr/bin/python
>>> addressInNetwork('188.104.8.64','172.16.0.0/12')
>>>True which is completely WRONG!!

Так что моя новая функция addressInNetwork выглядит так:


#!/usr/bin/python
import socket,struct
def addressInNetwork(ip,net):
    '''This function allows you to check if on IP belogs to a Network'''
    ipaddr = struct.unpack('=L',socket.inet_aton(ip))[0]
    netaddr,bits = net.split('/')
    netmask = struct.unpack('=L',socket.inet_aton(calcDottedNetmask(bits)))[0]
    network = struct.unpack('=L',socket.inet_aton(netaddr))[0] & netmask
    return (ipaddr & netmask) == (network & netmask)

def calcDottedNetmask(mask):
    bits = 0
    for i in xrange(32-int(mask),32):
        bits |= (1 > 24, (bits & 0xff0000) >> 16, (bits & 0xff00) >> 8 , (bits & 0xff))


И теперь ответ правильный!!!


#!/usr/bin/python
>>> addressInNetwork('188.104.8.64','172.16.0.0/12')
False

Я надеюсь, что это поможет другим людям, сэкономив им время!

1
ответ дан 24 November 2019 в 07:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: