我有一个Python脚本来收集ip地址的主机名,其中primes作为字节实体。 例如,根据我的问题集,211.13.17.2是一个有效的ip,其中每个字节实体(十进制表示)都是素数。
代码:
from itertools import product
import socket
# prime or not
def prime(n):
if n > 1:
p = 0
for i in range(2, n-1):
if divmod(n, i)[1] == 0:
p = 1
break
if p == 0:
return True
def get_host_name(b1, b2, b3, b4):
addr = str(b1) + '.' + str(b2) + '.' + str(b3) + '.' + str(b4)
try:
return socket.gethostbyaddr(addr)
except socket.herror:
pass
# find host names whose ip addresses are all primes
byte = [b for b in range(0, 256) if prime(b)]
ips = list(product(byte, byte, byte, byte))
print 'Total ips = ', len(ips)
for ip in ips:
if get_host_name(*ip):
print get_host_name(*ip)
问题是我的脚本太慢了。我需要专家帮助来优化此代码。请查明所有错误以及使其表现得更快的方法。
答案 0 :(得分:1)
对于素数,你可以使用这样的东西,
import numpy as np
isprime = lambda x: np.all(np.mod(x, range(2, 1 + int(np.sqrt(x)))))
primes = np.array([ x for x in range(2, 255) if isprime(x) ])
你可以通过
获得ip地址的生成器('{}.{}.{}.{}'.format(*x) for x in itertools.product(primes, repeat=4))
但很可能代码在socket
部分很慢,并且因为它需要检查的组合数量;为此,您可以通过使用工作流程池来尝试并行性;像这样的东西:
from multiprocessing import Pool
from socket import gethostbyaddr
def gethost(addr):
try:
return gethostbyaddr(addr)
except:
pass
if __name__ == '__main__':
p = Pool(3)
print (p.map(gethost,['74.125.228.137',
'11.222.333.444',
'17.149.160.49',
'98.139.183.24']))
编辑:对于只有少于50的素数,(50K +组合)和20个工作进程,我的机器上需要将近6分钟才能找到16K +结果。所以,有了这么多组合,并行性就无济于事。