用Python生成随机IP地址字符串

32
在Python中,如果我想生成一个形式为IP地址的随机字符串,应该怎么做?
例如:"10.0.1.1""10.0.3.14""172.23.35.1"等。
有人能给我一些帮助吗?
11个回答

59
>>> import random
>>> import socket
>>> import struct
>>> socket.inet_ntoa(struct.pack('>I', random.randint(1, 0xffffffff)))
'197.38.59.143'
>>> socket.inet_ntoa(struct.pack('>I', random.randint(1, 0xffffffff)))
'228.237.175.64'

注意:这可能会生成像 0.0.0.0255.255.255.255 这样的IP地址。


2
如果我想获取一个IPv6地址,我应该怎么做?谢谢! - changzhi
如果我想生成一个特定范围内的IP地址(例如在1.2.4.8和8.4.2.1之间),该怎么办? - Ahmed Hussein
2
@AhmedHussein for n in range(0x01020408, 0x08040201): ... socket.inet_ntoa(...) - falsetru
这实际上不能生成 0.0.0.0,因为 randint 从 1 开始,对吧?同样地,可以简单使用 0xfffffffe 来避免 255.255.255.255,对吗? - MappaM
@MappaM,你是对的。或者,你可以使用random.randrange(1, 0xffffffff),它会排除0xffffffff。请参见https://docs.python.org/3/library/random.html#random.randrange - falsetru
显示剩余2条评论

39

如果你只想要一个字符串:

import random

ip = ".".join(map(str, (random.randint(0, 255) 
                        for _ in range(4))))

11
你可以拿出地图,然后执行 ".".join(str(randint(0, 255)) for _ in range(4)) 这段代码。 - Joohwan

16

8
你还可以使用Python的 ipaddress 模块,该模块可广泛用于创建、操作和处理IPv4和IPv6地址和网络。
import ipaddress
import random

MAX_IPV4 = ipaddress.IPv4Address._ALL_ONES  # 2 ** 32 - 1
MAX_IPV6 = ipaddress.IPv6Address._ALL_ONES  # 2 ** 128 - 1


def random_ipv4():
    return  ipaddress.IPv4Address._string_from_ip_int(
        random.randint(0, MAX_IPV4)
    )

def random_ipv6():
    return ipaddress.IPv6Address._string_from_ip_int(
        random.randint(0, MAX_IPV6)
    )

示例:

>>> random.seed(444)                                                                                                                                                                                                                                         
>>> random_ipv4()                                                                                                                                                                                                                                            
'79.19.184.109'
>>> random_ipv4()                                                                                                                                                                                                                                            
'3.99.136.189'
>>> random_ipv4()                                                                                                                                                                                                                                            
'124.4.25.53'
>>> random_ipv6()                                                                                                                                                                                                                                            
'4fb7:270d:8ba9:c1ed:7124:317:e6be:81f2'
>>> random_ipv6()                                                                                                                                                                                                                                            
'fe02:b348:9465:dc65:6998:6627:1300:29c9'
>>> random_ipv6()                                                                                                                                                                                                                                            
'74a:dd88:1ff2:bfe3:1f3:81ad:debd:db88'

我有一个可能很蠢的问题,无法从文档或谷歌上澄清 - 为什么ipaddress.IPv4Address._ALL_ONES / ipaddress.IPv6Address._ALL_ONES会给我们IP地址总数减1?是否有一个地址保留作为广播地址?谢谢。 - mmTmmR
不要忘记零。这是第一个有效的IP地址 @mmTmmR - Brad Solomon
1
哈哈,谢谢。我觉得是我盯着屏幕太久了自己都搞混了!感谢你的解决方案,正是我想要的! - mmTmmR
在我的代码其他部分,我使用了 np.random.randint() 函数。为了保持一致性,我尝试将 random.randint(0, MAX_IPV4/6) 替换为 np.random.randint(0, (MAX_IPV4/6+1))。(由于 np.random.randint() 不包含上界值,因此我将 MAX_IPV4/MAX_IPV6 的值加1处理。)对于 IPV4 版本,根据您之前的回答,这个方法行得通。但是当我尝试进行 IPV6 版本时,出现了以下错误:“ValueError: high is out of bounds for int64”。您对这个错误有什么想法吗?我需要将 IPV6 的结果转换为其他数据类型吗?谢谢。 - mmTmmR
1
@mmTmmR np.random.randint() 只能生成最大值为 2 ** 64 - 1 的 64 位整数,而 ipaddress.IPv6Address._ALL_ONES 是 128 位的。如果您只需要一个随机地址,请使用 random;NumPy 是为数组设计的。 - Brad Solomon

8

一种生成类似于IP地址的随机字符串的替代方法是:

>>> ip = '{}.{}.{}.{}'.format(*__import__('random').sample(range(0,255),4))
>>> ip
'45.162.105.102'

6
In [123]: '.'.join('%s'%random.randint(0, 255) for i in range(4))
Out[123]: '45.204.56.200'

In [124]: '.'.join('%s'%random.randint(0, 255) for i in range(4))
Out[124]: '7.112.222.205'

被低估的答案。很好的生成IP地址的方法,不需要外部依赖。 - Georgi Karadzhov

1

也许太显而易见了,但如果您需要在范围内随机IP地址,可以使用以下方法:

import random

for x in xrange(1,100):
  ip = "192.168."
  ip += ".".join(map(str, (random.randint(0, 255) 
                          for _ in range(2))))

  print ip

1

1
如果仅基于用户空间(192.168.xxx.xxx,172.16.xxx.xxx-172.31.255.255和10.xxx.xxx.xxx)生成私有IP地址,则可以参考帖子提供的良好答案。
如果您尝试生成任何其他被认为是公共的东西,请使用以下代码(我的代码基于上述帖子):
import random
def randomPublicIPaddress():
    '''
    oct 1 - cant be 10
    oct 2 - if oct1 == 192
                cant be 168
            if oct1 == 172
                cant be 16-31
    oct 3 - can be anything
    oct 4 - can be anything
    '''
    oct1 = random.choice([i for i in range(0,255) if i not in [10,127]])
    if oct1 == 192:
        oct2 = random.choice([i for i in range(0,255) if i not in [168]])
    elif oct1 == 172:
        oct2 = random.choice([i for i in range(0,255) if i not in range(16,31)])
    else:
        oct2 = random.randint(0,255)
    oct3 = random.randint(0,255)
    oct4 = random.randint(0,255)

    return ".".join(map(str,([oct1,oct2,oct3,oct4])))

警告,还有许多其他被视为“私有”的IP地址范围,请确保在 IANA上查看列表。


1

更快:Mimesis

如果您想要更快的速度,请尝试使用Mimesis

from mimesis import Internet 
random_ip = Internet().ip_v4()

enter image description here

具有有效CIDR的IP:Faker

如果您想生成具有有效CIDR的随机IP地址,请尝试使用Faker

from faker import Faker  
random_valid_ip = Faker().ipv4()  

enter image description here

如果想了解为什么Faker需要更长的时间,请查看这个问题


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接