2016-10-09 86 views
2

我想写一些代码,可以快速返回一个正确压缩的IPv6地址。我试过...快速Python的IPv6压缩

socket.inet_pton(socket.AF_INET6,socket.inet_PTON(socket.AF_INET6,address)) 
ipaddress.IPv6Address(address) 
IPy.IP(address) 

...从处理IPv6压缩的速度越快越慢。第一个是最快的(每65,565个IP地址〜3.6秒),第二个比第一个快不到一半(每个65,565个IP地址〜8.4秒),最后一个几乎是第二个(~14.4秒每65,565个IP地址)。

于是,我开始着手创建自己的...

import re 
from ipaddress import IPv6Address 

IPaddlist = [ 
    '2001:db8:00:0:0:0:cafe:1111', 
    '2001:db8::a:1:2:3:4', 
    '2001:0DB8:AAAA:0000:0000:0000:0000:000C', 
    '2001:db8::1:0:0:0:4', 
    '2001:4958:5555::4b3:ffff', 
    ] 

for addr in IPaddlist: 
    address = ":".join('' if i=='0000' else i.lstrip('0') for i in addr.split(':')) 
    address2 = (re.sub(r'(:)\1+', r'\1\1', address).lower()) 
    print(address2) 
    print(IPv6Address(addr)) 
    print('\n') 

它返回:

2001:db8::cafe:1111 
2001:db8::cafe:1111 

2001:db8::a:1:2:3:4 
2001:db8:0:a:1:2:3:4 

2001:db8:aaaa::c 
2001:db8:aaaa::c 

2001:db8::1::4 
2001:db8:0:1::4 

2001:4958:5555::4b3:ffff 
2001:4958:5555::4b3:ffff 

每个条目的第一行是我的代码,第二个是正确的压实,使用ipaddress.IPv6Address。

正如你所看到的,我很接近,但你知道他们说的“亲密”什么......

任何人有任何指针?我似乎遇到了障碍。

+0

的问题是,你也可以用'::'紧凑型最长的零序列。一个简单的正则表达式*不能*处理这种上下文信息...但是你可以尝试检查事实。所以看看'::'是否出现至少两次,如果是这样,确定哪个是正确的出现,并用':0:'替换其他的。 – Bakuriu

回答

0

只需使用socket函数。的代码在你的问题的第一行是比你的字符串操作快了近10倍:

from socket import inet_ntop, inet_pton, AF_INET6 
def compact1(addr, inet_ntop=inet_ntop, inet_pton=inet_pton, AF_INET6=AF_INET6): 
    return inet_ntop(AF_INET6, inet_pton(AF_INET6, addr)) 

from ipaddress import IPv6Address 
def compact2(addr, IPv6Address=IPv6Address): 
    return IPv6Address(addr) 

import re 
def compact3(addr, sub=re.sub): 
    address = ":".join('' if i=='0000' else i.lstrip('0') for i in addr.split(':')) 
    return sub(r'(:)\1+', r'\1\1', address).lower() 

现在让我们%timeit

In[9]: ips = [':'.join('{:x}'.format(random.randint(0, 2**16 - 1)) for i in range(8)) for _ in range(65565)] 

In[10]: %timeit for ip in ips: compact1(ip) 
10 loops, best of 3: 52.9 ms per loop 

In[11]: %timeit for ip in ips: compact2(ip) 
1 loop, best of 3: 715 ms per loop 

In[12]: %timeit for ip in ips: compact3(ip) 
1 loop, best of 3: 411 ms per loop 
+0

感谢您对Skovorodkin进行计时。出于某种原因,计时模块不会安装在我的Windows版本的Python上,所以我不得不依赖于创建自己的计时代码,这是我通过查看IP地址工作速度有多快而开始的,从'::',并查看完成的每个八位字节。我希望能够把它变成一个.pyd文件,如果我能够足够快的话。部分问题是我目前被迫使用ipaddress.IPv6Address,因为我的代码只是使用基本IP地址('::')的循环和整数加法,而不是生成完整的IPv6地址。 – PyNewbie

+0

在试图生成完整IPv6地址的代码中,它还会在每个八位字节中生成零,我试图将其删除。是否有代码生成快速的兼容压缩IPv6地址?我的IPv4代码可以在25分钟25秒内搜索所有IPv4地址的MD5哈希... IPv6代码速度慢8倍(由于使用ipaddress.IPv6Address),这是一个问题,因为IPv6地址空间有多大是。 – PyNewbie