一、初衷:
一般在CMDB里會存儲一台服務器的內網IP、管理IP、電信IP、聯通IP,我們在使用的時候只需要拿到其中一個外網IP地址即可。那么我們就需要判斷內網IP、管理IP並剔除掉,獲取第一個外網IP。
例如三線機房服務器:10.20.0.111(內網IP),221.222.222.33, 8.8.8.8, 1114.114.144.114, 10.20.1.100(管理IP)
二、原理代碼:
內網IP可分為三類:
- A類地址:10.0.0.0--10.255.255.255
- B類地址:172.16.0.0--172.31.255.255
- C類地址:192.168.0.0--192.168.255.255
局域網在選取使用私有地址時,一般會按照實際需要容納的主機數來選擇私有地址段。常見的局域網由於容量小,一般選擇C類的192.168.0.0作為地址段使用,一些大型企業就需要使用B類甚至A類地址段作為內部網絡的地址段。
實現代碼:
1 def ip_into_int(ip): 2 # 先把 192.168.1.13 變成16進制的 c0.a8.01.0d ,再去了“.”后轉成10進制的 3232235789 即可。 3 # (((((192 * 256) + 168) * 256) + 1) * 256) + 13 4 return reduce(lambda x,y:(x<<8)+y,map(int,ip.split('.'))) 5 6 def is_internal_ip(ip): 7 ip = ip_into_int(ip) 8 net_a = ip_into_int('10.255.255.255') >> 24 9 net_b = ip_into_int('172.31.255.255') >> 20 10 net_c = ip_into_int('192.168.255.255') >> 16 11 return ip >> 24 == net_a or ip >>20 == net_b or ip >> 16 == net_c 12 13 if __name__ == '__main__': 14 ip = '192.168.0.1' 15 print ip, is_internal_ip(ip) 16 ip = '10.2.0.1' 17 print ip, is_internal_ip(ip) 18 ip = '172.16.1.1' 19 print ip, is_internal_ip(ip)
運行結果:
[root@ ubuntu]$ python p.py 192.168.0.1 True 10.2.0.1 True 172.16.1.1 True
其中map和reduce函數的用法介紹:
>>> map(int, '12.34'.split('.')) [12, 34] >>> reduce(lambda x,y:(x<<8)+y, [12, 34]) 3106 # 左移8位,相當於乘以256 >>> 12 * 256 + 34 3106
三、實例
1 #!/usr/bin/python 2 #-*-coding:utf8-*- 3 4 vid = [] 5 real_host = {} 6 7 #判斷內網IP 8 def ip_into_int(ip): 9 return reduce(lambda x,y:(x<<8)+y,map(int,ip.split('.'))) 10 11 def is_internal_ip(ip): 12 ip = ip_into_int(ip) 13 net_a = ip_into_int('10.255.255.255') >> 24 14 net_b = ip_into_int('172.31.255.255') >> 20 15 net_c = ip_into_int('192.168.255.255') >> 16 16 return ip >> 24 == net_a or ip >>20 == net_b or ip >> 16 == net_c 17 18 ef get_ips(vid): 19 20 t = len(vid) 21 for i in range(t): 22 host_ip = [] 23 ips_url = 'http://www.google.com/IP.do?versionId=%d ' % vid[i] 24 ips =urllib2.urlopen(ips_url) 25 ips_json = json.loads(ips.read()) 26 27 t2 = len(ips_json['object']) 28 for k in range(t2): 29 flag = 0 30 ip_list = ips_json['object'][k].split(',') 31 32 t3 =len(ip_list) 33 for m in range(t3): 34 if flag ==0 and is_internal_ip(ip_list[m]) == False: 35 host_ip.append(ip_list[m]) 36 flag = 1 37 38 real_host[vid[i]] = host_ip 39 40 ips.close() 41 return real_host
其中ip_list = [10.20.0.111, 221.222.222.33, 8.8.8.8, 1114.114.144.114, 10.20.1.100],通過循環依次取IP地址,判斷后存第一個IP到host_ip[]。並設置flag =1 說明已取到此機器的外網IP,可以去下一個機器的了。