【问题标题】:Python script to collect all hostnames of ip addresses with only prime entities用于收集仅具有主要实体的 IP 地址的所有主机名的 Python 脚本
【发布时间】:2014-01-10 10:26:06
【问题描述】:

我有一个 Python 脚本来收集以素数为字节实体的 IP 地址的主机名。 例如,根据我的问题集,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)

问题是我的脚本太慢了。我需要专家帮助来优化此代码。请指出所有错误以及使其表现更快的方法。

【问题讨论】:

  • 学习使用 Python 分析器:docs.python.org/2/library/profile.html 并确定代码的哪个部分最慢。我希望您的代码中最慢的部分是对数千个 IP 地址的名称查找。
  • 代码需要多长时间,你需要多长时间?唯一会产生显着差异(超过 2 倍)的是同时运行多个请求。所以你需要多线程或者多进程,或者异步DNS请求:catonmat.net/blog/asynchronous-dns-resolution
  • 正如尼尔建议的那样:python -m cProfile myscript.py

标签: python sockets networking python-2.7 ip


【解决方案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+ 的结果。因此,对于如此大量的组合,并行性无济于事。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 2016-03-24
    • 1970-01-01
    • 2016-01-06
    • 2023-03-05
    • 1970-01-01
    • 2023-03-28
    相关资源
    最近更新 更多