在Python中生成IP范围

时间:2013-10-03 10:53:11

标签: python

如果我输入IP“ 127 ”: 我希望生成从 127.0.0.1 127.255.255.255

的所有内容

如果我输入IP“ 127.0 ” 我希望生成从 127.0.0.1 127.0.255.255

的所有内容

如果我输入IP“ 127.0.0 ” 我希望生成从 127.0.0.1 127.0.0.255

的所有内容

使用netaddr

3 个答案:

答案 0 :(得分:6)

最初的问题基于bash ..如果你只想要纯python实现,请向下滚动:

我认为你的具体问题可能会因为一些痛苦而在bash中解决,但这是对一般问题的抨击:

因此,首先,值得注意的是并非所有特定范围内的IP地址都是有效的主机地址。具体而言,第一个和最后一个地址在IPv4(网络/广播)中保留。

其次,IPv4地址,比如192.168.0.1,实际上只是一个32位/ 4字节的数字,它被分成4个8位/ 1字节的块。但是,您没有将地址的网络/主机部分拆分为8位边界。例如,127.0.0.0 / 24将分割放在第三个点(24位)并包含主机地址127.0.0.1-254,但你可以将它分成28位,例如127.0.0.0/28,其中包含主机127.0.0.1-14。

第三,生成您要求的数据的“正确”方式(我相信)是将IP地址转换为二进制,例如, 127.0.0.1 = 01111111000000000000000000000001,确定主机/网络分裂的位置(比如它是a / 28),修复前28位,然后计算二进制数,然后根据需要转换回点分十进制表示:

01111111000000000000000000000001 = .1
---------fixed--------------**** ** variable

so you get:
01111111000000000000000000000010 = .2
01111111000000000000000000000011 = .3

在bash中执行此操作当然是一种痛苦。

现在,如果你有Python3可用,你可以使用ipaddress模块在​​给定网络上生成所有有效的主机地址(见下文)。

>>> import ipaddress
>>> print("\n".join([str(x) for x in ipaddress.ip_network("192.0.2.0/28").hosts()]))
192.0.2.1
192.0.2.2
192.0.2.3
192.0.2.4
192.0.2.5
192.0.2.6
192.0.2.7
192.0.2.8
192.0.2.9
192.0.2.10
192.0.2.11
192.0.2.12
192.0.2.13
192.0.2.14

此模块还偶然支持IPv6,因此您可以使用2001:0db8::/120生成ipaddress.ip_network("2001:0db8::/120").hosts()的主机。

你可以(虽然你不必)将它包装在一个与shell脚本兼容的单行内容中。

python3 -c 'import ipaddress; print("\n".join([str(x) for x in ipaddress.ip_network("192.0.2.0/28").hosts()]))'

现在,您需要的只是

#!/bin/bash
# split it up
IFS='.' read -a array <<< "127.0.0"
#echo ${array[*]}
#127 0 0

mask=$(( ${#array[@]} * 8))
# 28

# add missing 0s.
for $i in {1..4}; do
   if [ i -gt ${#array[@]} ]; then
      array[i]="0"
   fi
done
#echo ${array[*]}
#127 0 0 0


# join, see http://stackoverflow.com/questions/1527049/bash-join-elements-of-an-array
SAVE_IFS=$IFS
IFS="."
full_ip="${array[*]}"
IFS=$SAVE_IFS
# 127.0.0.0

# now add /mask
network="$full_ip/$mask"
# 127.0.0.0/24

python3 -c "import ipaddress; print(\"\\n\".join([str(x) for x in ipaddress.ip_network(\"$network\").hosts()]))"
#127.0.0.1
#127.0.0.2
# ...
#127.0.0.254

Pure Python3:

import ipaddress
input="127.0.0"
input_arr=input.split(".") # ['127', '0', '0']
netmask=len(input_arr)*8  # 24
for i in range(len(input_arr), 4):
     input_arr.append('0')
# input_arr = ['127', '0', '0', '0']
ip='.'.join(input_arr)  # '127.0.0.0'
network=ip + '/' + str(netmask)  # '127.0.0.0/24'
print("\n".join([str(x) for x in ipaddress.ip_network(network).hosts()]))

如果您想添加网络/广播,请另外打印.network_address.broadcast_address

答案 1 :(得分:1)

def iprange(ip1,ip2):
 print(f'list of ip adresses between {ip1} and {ip2}') # list IPs between 127.0.0.1 and 127.0.0.100
 ip1_1 = ip1.split(".")
 ip2_2 = ip2.split(".")

for i in range(0, len(ip1_1)):
    ip1_1[i] = int(ip1_1[i])
for i in range(0, len(ip2_2)):
    ip2_2[i] = int(ip2_2[i])

for i in range(ip1_1[0], ip2_2[0]+1):
    for j in range(ip1_1[1], ip2_2[1]+1):
        for k in range(ip1_1[2], ip2_2[2]+1):
            for z in range(ip1_1[3], ip2_2[3]+1):
                print(f'{i}.{j}.{k}.{z}')

iprange("127.0.0.1","127.0.0.15")

答案 2 :(得分:0)

这是一种蛮力方法:

#! /bin/bash
IFS=.
set -- $1
a=$1; b=$2; c=$3; d=$4
if [[ -z $d ]]; then
    for d in {0..255}; do
        if [[ -z $c ]]; then
            for c in {0..255}; do
                if [[ -z $b ]]; then
                    for b in {0..255}; do
                        echo $a.$b.$c.$d
                    done
                    unset b
                else
                    echo $a.$b.$c.$d
                fi
            done
            unset c
        else
            echo $a.$b.$c.$d
        fi
    done
    unset d
else
    echo $a.$b.$c.$d
fi

一些测试:

$ bash iprange.sh 127.0.0.1
127.0.0.1
$ bash iprange.sh 127.0.0 | sed -n '1,5p;$p'
127.0.0.0
127.0.0.1
127.0.0.2
127.0.0.3
127.0.0.4
127.0.0.255
$ bash iprange.sh 127.0.0 | wc
    256     256    2962
$ bash iprange.sh 127.0 | sed -n '1,5p;$p'
127.0.0.0
127.0.1.0
127.0.2.0
127.0.3.0
127.0.4.0
127.0.255.255
$ bash iprange.sh 127.0 | wc
  65536   65536  861184