简体   繁体   English

如何从 Python 中的 IP 范围列表中生成所有可能的 IP?

[英]How can I generate all possible IPs from a list of ip ranges in Python?

Let's say I have a text file contains a bunch of ip ranges like this:假设我有一个文本文件包含一堆这样的 ip 范围:

x.x.x.x-y.y.y.y
x.x.x.x-y.y.y.y
x.x.x.x-y.y.y.y
x.x.x.x-y.y.y.y
x.x.x.x-y.y.y.y

xxxx is start value and yyyy is end value of range. xxxx 是起始值,yyyy 是范围的结束值。

How can I convert these ip ranges to all possible IPs in a new text file in python?如何在 python 的新文本文件中将这些 IP 范围转换为所有可能的 IP?

PS: This question is not same as any of my previous questions. PS:这个问题和我之前的任何问题都不一样。 I asked "how to generate all possible ips from cidr notations" in my previous question.我在上一个问题中问过“如何从 cidr 符号生成所有可能的 ips”。 But in here I ask "how to generate from ip range list".但是在这里我问“如何从ip范围列表生成”。 These are different things.这些是不同的东西。

This function returns all ip addresses like from start to end:此函数从头到尾返回所有 IP 地址:

def ips(start, end):
    import socket, struct
    start = struct.unpack('>I', socket.inet_aton(start))[0]
    end = struct.unpack('>I', socket.inet_aton(end))[0]
    return [socket.inet_ntoa(struct.pack('>I', i)) for i in range(start, end)]

These are the building blocks to build it on your own:这些是您自己构建它的构建块:

>>> import socket, struct
>>> ip = '0.0.0.5'
>>> i = struct.unpack('>I', socket.inet_aton(ip))[0]
>>> i
5
>>> i += 1
>>> socket.inet_ntoa(struct.pack('>I', i))
'0.0.0.6'

Example:例子:

ips('1.2.3.4', '1.2.4.5')
['1.2.3.4', '1.2.3.5', '1.2.3.6', '1.2.3.7', ..., '1.2.3.253', '1.2.3.254', '1.2.3.255', '1.2.4.0', '1.2.4.1', '1.2.4.2', '1.2.4.3', '1.2.4.4']

Read from file从文件中读取

In your case you can read from a file like this:在您的情况下,您可以从这样的文件中读取:

with open('file') as f:
    for line in f:
        start, end = line.strip().split('-')
        # ....

Python 3 only, for IPv4, same idea with @User but use new Python3 standard library: ipaddress仅限 Python 3,对于 IPv4,与 @User 的想法相同,但使用新的 Python3 标准库: ipaddress

IPv4 is represented by 4 bytes. IPv4 由 4 个字节表示。 So next IP is actually next number, a range of IPs can be represented as a range of integer numbers.所以next IP其实就是next number,一个IP范围可以表示为一个整数范围。

0.0.0.1 is 1 0.0.0.1 是 1

0.0.0.2 is 2 0.0.0.2 是 2

... ...

0.0.0.255 is 255 0.0.0.255 是 255

0.0.1.0 is 256 0.0.1.0 是 256

0.0.1.1 is 257 0.0.1.1 是 257

By code (ignore the In []: and Out []:)通过代码(忽略 In []: 和 Out []:)

In [68]: from ipaddress import ip_address

In [69]: ip_address('0.0.0.1')
Out[69]: IPv4Address('0.0.0.1')

In [70]: ip_address('0.0.0.1').packed
Out[70]: b'\x00\x00\x00\x01'

In [71]: int(ip_address('0.0.0.1').packed.hex(), 16)
Out[71]: 1

In [72]: int(ip_address('0.0.1.0').packed.hex(), 16)
Out[72]: 256

In [73]: int(ip_address('0.0.1.1').packed.hex(), 16)
Out[73]: 257

ip.packed.hex() returns the hexadecimal form of 4 bytes, as it is in hexadecimal, it is shorter (eg: 0xff hex == 255 decimal == 0b11111111 binary), and thus, often used for representing bytes. ip.packed.hex()返回 4 个字节的十六进制形式,因为它是十六进制,所以它更短(例如:0xff 十六进制 == 255 十进制 == 0b11111111 二进制),因此,通常用于表示字节。 int(hex, 16) returns integer value corresponding to the hex value as it is more human friendly, and can be used as input for ip_address . int(hex, 16)返回与十六进制值对应的整数值,因为它更人性化,并且可以用作ip_address的输入。

from ipaddress import ip_address

def ips(start, end):
    '''Return IPs in IPv4 range, inclusive.'''
    start_int = int(ip_address(start).packed.hex(), 16)
    end_int = int(ip_address(end).packed.hex(), 16)
    return [ip_address(ip).exploded for ip in range(start_int, end_int)]


ips('192.168.1.240', '192.168.2.5')

Returns:回报:

['192.168.1.240',
 '192.168.1.241',
 '192.168.1.242',
 '192.168.1.243',
 '192.168.1.244',
 '192.168.1.245',
 '192.168.1.246',
 '192.168.1.247',
 '192.168.1.248',
 '192.168.1.249',
 '192.168.1.250',
 '192.168.1.251',
 '192.168.1.252',
 '192.168.1.253',
 '192.168.1.254',
 '192.168.1.255',
 '192.168.2.0',
 '192.168.2.1',
 '192.168.2.2',
 '192.168.2.3',
 '192.168.2.4']

try This:尝试这个:

def ip_range(start_ip,end_ip):
start = list(map(int,start_ip.split('.')))
end = list(map(int,end_ip.split('.')))
iprange=[]
while start!=list(map(int,end_ip.split('.'))):
    for i in range(len(start)-1,-1,-1):
        if start[i]<255:
            start[i]+=1
            break
        else:
            start[i]=0
    iprange.append('.'.join(map(str,start)))
return iprange

Use ipaddress and range()使用 ipaddress 和 range()

import ipaddress

print([ipaddress.ip_address(i).exploded for i in range(int(ipaddress.ip_address(first_ip)), int(ipaddress.ip_address(last_ip)))])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM