2016-10-09 2 views
2

제대로 압축 된 IPv6 주소를 신속하게 반환 할 수있는 코드를 작성하려고합니다. 나는 시도했다 ...빠른 파이썬 IPv6 압축

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

... IPv6 컴파일을 처리하는 속도가 더 빠르다. 첫 번째 IP 주소는 가장 빠르며 (IP 주소 65,565 개당 3.6 초), 두 번째 IP 주소는 IP 주소 65,565 개당 8.4 초 미만이며, 마지막 IP 주소는 두 번째 IP 주소보다 거의 두 배 빠릅니다 (~ 14.4 초 65,565 IP 주소 당). ,

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 

는 각 항목의 첫 번째 줄은 내 코드입니다, 두 번째는 올바른 압축입니다 :

그래서, 나는 그것은 반환 ... 내 자신을 만들 수

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') 

을 설정 ipaddress.IPv6Address를 사용합니다.

당신이 볼 수 있듯이, 내가 가까이 해요,하지만 당신은 그들이 '가까운'에 대해 뭐라고하는지 알아요 ...

누구나 어떤 포인터가? 나는로드 블록을 쳤던 것 같다.

+0

문제는 당신은 또한'사용할 수있는 ::'컴팩트하는 것입니다 귀하의 질문에 코드의 첫 번째 줄은 거의 10 배 빠른 당신의 문자열 조작보다 가장 긴 0의 순서. 간단한 정규식 *은이 문맥 정보를 처리 할 수 ​​없습니다 ... 그러나 사실을 확인하려고 할 수 있습니다. 따라서'::'가 적어도 두 번 나타나는지 확인하고, 그렇다면 올바른 것을 발견하고 다른 것을': 0 :'으로 대체하십시오. – Bakuriu

답변

0

그냥 socket 기능을 사용하십시오.

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 파일로 바꾸기를 바랐다. 문제의 일부는 현재 전체 ip 주소를 생성하는 대신 기본 IP 주소 ('::')에 루프 및 정수를 추가하기 때문에 ipaddress.IPv6Address를 사용해야한다는 것입니다. – PyNewbie

+0

전체 IPv6 주소를 생성하려고 시도하는 코드로 이동하면서 각 옥텟에 0을 생성합니다.이 옥텟은 제거하려고했습니다. 빠른 호환 IPv6 주소를 생성하는 코드가 있습니까? 내 IPv4 코드는 25 분 25 초 내에 모든 IPv4 주소의 MD5 해시를 검색 할 수 있습니다. IPv6 코드는 IPv6 주소 공간이 얼마나 큰지를 고려할 때 (ipaddress.IPv6Address 사용으로 인해) 8 배 더 느립니다. 입니다. – PyNewbie