2016-10-09 95 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