Как я могу проверить, есть ли ip в сети на Python? - PullRequest
85 голосов
/ 04 мая 2009

Учитывая IP-адрес (скажем, 192.168.0.1), как мне проверить, находится ли он в сети (скажем, 192.168.0.0/24) в Python?

Существуют ли в Python общие инструменты для манипулирования IP-адресами? Такие вещи, как поиск хоста, IP-адрес для INT, сетевой адрес с маской сети для INT и так далее? Надеюсь, в стандартной библиотеке Python для 2.5.

Ответы [ 25 ]

1 голос
/ 11 января 2013

Относительно всего вышесказанного, я думаю, socket.inet_aton () возвращает байты в сетевом порядке, поэтому правильный способ их распаковки, вероятно,

struct.unpack('!L', ... )
0 голосов
/ 19 июля 2018

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

Я протестировал его и работает, по крайней мере, на архитектурах с прямым порядком байтов - например, x86 - если кому-то нравится примерять архитектуру с прямым порядком байтов, пожалуйста, дайте мне отзыв.

IP2Int код взят из этого поста , другой метод - полностью (для моих тестовых случаев) исправление предыдущих предложений в этом вопросе.

код:

def IP2Int(ip):
    o = map(int, ip.split('.'))
    res = (16777216 * o[0]) + (65536 * o[1]) + (256 * o[2]) + o[3]
    return res


def addressInNetwork(ip, net_n_bits):
    ipaddr = IP2Int(ip)
    net, bits = net_n_bits.split('/')
    netaddr = IP2Int(net)
    bits_num = int(bits)
    netmask = ((1L << bits_num) - 1) << (32 - bits_num)
    return ipaddr & netmask == netaddr & netmask

Надеюсь, полезно,

0 голосов
/ 10 октября 2017

Если вы не хотите импортировать другие модули, вы можете использовать:

def ip_matches_network(self, network, ip):
    """
    '{:08b}'.format(254): Converts 254 in a string of its binary representation

    ip_bits[:net_mask] == net_ip_bits[:net_mask]: compare the ip bit streams

    :param network: string like '192.168.33.0/24'
    :param ip: string like '192.168.33.1'
    :return: if ip matches network
    """
    net_ip, net_mask = network.split('/')
    net_mask = int(net_mask)
    ip_bits = ''.join('{:08b}'.format(int(x)) for x in ip.split('.'))
    net_ip_bits = ''.join('{:08b}'.format(int(x)) for x in net_ip.split('.'))
    # example: net_mask=24 -> compare strings at position 0 to 23
    return ip_bits[:net_mask] == net_ip_bits[:net_mask]
0 голосов
/ 17 апреля 2017

Вот мой код

# -*- coding: utf-8 -*-
import socket


class SubnetTest(object):
    def __init__(self, network):
        self.network, self.netmask = network.split('/')
        self._network_int = int(socket.inet_aton(self.network).encode('hex'), 16)
        self._mask = ((1L << int(self.netmask)) - 1) << (32 - int(self.netmask))
        self._net_prefix = self._network_int & self._mask

    def match(self, ip):
        '''
        判断传入的 IP 是不是本 Network 内的 IP
        '''
        ip_int = int(socket.inet_aton(ip).encode('hex'), 16)
        return (ip_int & self._mask) == self._net_prefix

st = SubnetTest('100.98.21.0/24')
print st.match('100.98.23.32')
0 голосов
/ 20 августа 2015

Из различных источников выше, и из моего собственного исследования, так я получил подсчет адресов и подсчет. Этих частей достаточно, чтобы решить вопрос и другие связанные вопросы.

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

    @staticmethod
    def numToDottedQuad(n):
        "convert long int to dotted quad string"
        return socket.inet_ntoa(struct.pack('>L', n))

    @staticmethod
    def makeNetmask(mask):
        bits = 0
        for i in xrange(32-int(mask), 32):
            bits |= (1 << i)
        return bits

    @staticmethod
    def ipToNetAndHost(ip, maskbits):
        "returns tuple (network, host) dotted-quad addresses given"
        " IP and mask size"
        # (by Greg Jorgensen)
        n = iptools.dottedQuadToNum(ip)
        m = iptools.makeMask(maskbits)
        net = n & m
        host = n - mask
        return iptools.numToDottedQuad(net), iptools.numToDottedQuad(host)
...