2014-02-20 59 views
3

使用Python和bash的IP和端口,我想完成兩兩件事:處理在python和bash

  1. 需要在格式分割的IPv6地址和端口組合[FEC2 :: 10] :80到fec2 :: 10和80.

  2. 鑑於IP地址和端口的組合,我需要確定IP是v4還是v6地址。例如:1.2.3.4:80和[fec2 :: 10]:80

請建議一種方法。

謝謝!

示例代碼:

#!/usr/bin/env python 

import optparse 

def main(): 
    server = "[fec1::1]:80" 
    if server.find("[", 0, 2) == -1: 
     print "IPv4" 
     ip, port = server.split(':') 
    else: 
     print "IPv6" 
     new_ip, port = server.rsplit(':', 1) 
     print new_ip 
     ip = new_ip.strip('[]') 

    print ip 
    print port 

if __name__ == '__main__': 
    main() 

這適用於所有的情況下,當沒有一個端口被指定的輸入時除外。例如:10.78.49.50和[fec2 :: 10]

對此有何建議?

+1

那麼是什麼問題? – devnull

+0

我的bash和python腳本會收到IP:port組合作爲輸入,腳本需要確定IP的地址族,然後分割IP和端口。 – Maddy

回答

0

這是我想出的代碼。它看起來冗長而費力,但它解決了所有可能的輸入場景。任何建議濃縮/更好的是最受歡迎的:)

#!/usr/bin/env python 

import optparse 

def main(): 
    server = "[fec1::1]:80" 

    if server.find("[", 0, 2) == -1: 
     print "IPv4" 
     if server.find(":", 0, len(server)) == -1: 
      ip = server 
      port = "" 
     else: 
      ip, port = server.split(':') 
    else: 
     print "IPv6" 
     index = server.find("]", 0, len(server)) 
     if index == -1: 
      print "Something wrong" 
      new_ip = "" 
      port = "" 
     else: 
      if server.find(":", index, len(server)) == -1: 
      new_ip = server 
      port = "" 
      else: 
      new_ip, port = server.rsplit(':', 1) 
     print new_ip 
     ip = new_ip.strip('[]') 

    print ip 
    print port 

if __name__ == '__main__': 
    main() 
3

假設your_input就像"[fec2::10]:80""1.2.3.4:80",很容易分裂端口,找出IP地址:

#!/usr/bin/env python3 
from ipaddress import ip_address 

ip, separator, port = your_input.rpartition(':') 
assert separator # separator (`:`) must be present 
port = int(port) # convert to integer 
ip = ip_address(ip.strip("[]")) # convert to `IPv4Address` or `IPv6Address` 
print(ip.version) # print ip version: `4` or `6` 
+0

['ipaddress'](http://docs.python.org/3/library/ipaddress.html)模塊只是3.3版本的新增功能,如果某人正在運行較早版本的python,該怎麼辦?我認爲,通過這種方式找到版本更簡單,但不要誤會我的意思。 :) – 2rs2ts

+1

@ 2rs2ts:您可以在早期版本中使用['ipaddr-py'](https://code.google.com/p/ipaddr-py/)。 – jfs

+0

啊,很高興知道。但它仍然不是標準模塊的一部分。 – 2rs2ts

1

您可以使用urlparse(稱爲3.X urllib.parse)的URL分成每個組件:

>>> from urlparse import urlparse 
>>> ipv4address = urlparse("http://1.2.3.4:80") 
>>> ipv4address 
ParseResult(scheme='http', netloc='1.2.3.4:80', path='', params='', query='', fragment='') 
>>> ipv6address = urlparse("http://[fec2::10]:80") 
>>> ipv6address 
ParseResult(scheme='http', netloc='[fec2::10]:80', path='', params='', query='', fragment='') 

然後,你可以通過使用rfind找到最後一個冒號的指數分裂的端口關閉:

>>> ipv4address.netloc.rfind(':') 
7 
>>> ipv4address.netloc[:7], ipv4address.netloc[8:] 
('1.2.3.4', '80') 
>>> ipv6address.netloc.rfind(':') 
10 
>>> ipv6address.netloc[:10], ipv6address.netloc[11:] 
('[fec2::10]', '80') 

確定它的類型應該如if ':' in that_split_tuple[0]那樣簡單,對吧? (不是100%肯定,因爲自從我學會了如何在URL中寫的IPv6地址,它已經有一段時間。)

最後,從您的IPv6地址去掉括號很簡單,有很多方法可以做到這一點:

>>> ipv6address.netloc[:10].replace('[', '').replace(']', '') 
'fec2::10' 
>>> ipv6address.netloc[:10].strip('[]') 
'fec2::10' 

編輯

>>> import re 
>>> f = lambda(n): re.split(r"(?<=\]):" if n.startswith('[') else r"(?<=\d):", n) 
>>> f(ipv4address.netloc) 
['1.2.3.4', '80'] 
>>> f(ipv6address.netloc) 
['[fec2::10]', '80'] 
>>> f("1.2.3.4") 
['1.2.3.4'] 
>>> f("[fec2::10]") 
['[fec2::10]'] 

(我在遇到麻煩是與我的單組更聰明:因爲你表達了並不總是具有端口號的關注,你可以顯著使用regular expression簡化lar表達式,因此是內聯三元組)。

+0

我已經添加了一個與我的問題相關的與模塊無關的代碼。它不完整。有什麼建議嗎? – Maddy

+0

@Maddy好吧,在這一點上,我會爲你寫一個正則表達式,但是你需要告訴我,你是否總是要在你的IPv6地址中加括號,以及你是否要使用混合地址。 ':: FFFF:1.2.3.4'。 – 2rs2ts