在Python中生成IP范围

在Python中生成IP范围,python,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 使用NetAddress,这里有一种暴力方法: #! /bin/bash IFS=. set -- $1 a=$1; b=$2; c=$3; d=$4 if [[ -z $d ]]; then for d in {0..

如果我输入IP“127”: 我想生成从127.0.0.1127.255.255.255


如果我输入IP“127.0” 我想生成从127.0.0.1127.0.255.255


如果我输入IP“127.0.0” 我想生成从127.0.0.1127.0.0.255



使用NetAddress,这里有一种暴力方法:

#! /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

以下是一种暴力方法:

#! /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

最初的问题是基于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=011111000000000000000000000001
,确定主机/网络拆分位置(假设是a/28),修复前28位,然后计算二进制数,如果需要,再转换回点十进制表示:

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

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

在bash中这样做当然是一种痛苦

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

顺便说一下,此模块还支持IPv6,因此您可以使用
ipaddress.ip_网络(“2001:0db8::/120”).hosts()生成
2001:0db8::/120的主机

您可以(尽管不必)将其包装在与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

如果要添加网络/广播,只需另外打印
.network\u address
.broadcast\u address

原始问题基于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=011111000000000000000000000001
,确定主机/网络拆分位置(假设是a/28),修复前28位,然后计算二进制数,如果需要,再转换回点十进制表示:

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

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

在bash中这样做当然是一种痛苦

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

顺便说一下,此模块还支持IPv6,因此您可以使用
ipaddress.ip_网络(“2001:0db8::/120”).hosts()生成
2001:0db8::/120的主机

您可以(尽管不必)将其包装在与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

如果要添加网络/广播,只需另外打印
.network\u address
.broadcast\u address

可以从:
IFS=。eval set--$ip
(在只检查了数字和点之后),然后
$#
告诉您有多少个八位字节,等等。值得一提的是,我曾经尝试在
sh
中编写一些此类内容,但后来找到了Python
NetAddress
包,并切换到该包。:-)+1用于使用Python或其他语言。在Bash中执行此操作会有点棘手,没有什么好的理由。可以从:
IFS=。eval set--$ip
(在只检查了数字和点之后),然后
$#
告诉您有多少个八位字节,等等。值得一提的是,我曾经尝试在
sh
中编写一些此类内容,但后来找到了Python
NetAddress
包,并切换到该包。:-)+1用于使用Python或其他语言。在Bash中执行此操作将有点棘手,没有充分的理由。