亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

今天從Python/ target=_blank class=infotextkey>Python的角度來聊下計算機(jī)網(wǎng)絡(luò)這行基礎(chǔ)中的基礎(chǔ)的話題:網(wǎng)絡(luò)和IP地址計算(注:本文里的IP指的是IPv4,不涉及IPv6)。相信幾乎每位網(wǎng)工讀者在平時的工作和學(xué)習(xí)中都用過類似下圖的在線網(wǎng)絡(luò)和IP地址計算器吧:

用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

這類前人(或者說碼農(nóng)們)造出的輪子的確很好用,但是很少有網(wǎng)工明白它們背后的工作原理(也就是代碼是怎么寫出來的)。作為有志成?.NETDevOps Engineer的我們有必要深入的從代碼的角度來學(xué)習(xí)一下,不妨自己也用Python從零寫一個交互式的網(wǎng)絡(luò)和IP地址計算器,重新造一遍輪子,一來可以溫故知新,二來可以幫助我們更深入的了解二進(jìn)制和十進(jìn)制在Python里是怎么玩的。該交互式計算器的作用是讓用戶輸入一個合法的IP地址及子網(wǎng)掩碼,然后根據(jù)用戶輸入的信息自動給出用戶查詢的網(wǎng)段的網(wǎng)絡(luò)IP、廣播IP、網(wǎng)段內(nèi)可用的IP地址數(shù)、反掩碼以及用戶輸入的子網(wǎng)掩碼對應(yīng)的“/”格式的掩碼位(比如用戶輸入的掩碼是255.255.128.0,計算器會自動在結(jié)果中給出/17的掩碼位)。

因為是所有網(wǎng)工必須掌握的基本功,為了節(jié)約篇幅,下面我只高度概括一下網(wǎng)絡(luò)和IP地址計算的理論要點,我們重點要關(guān)注的是如何在Python中實現(xiàn)它們(所有演示我都將在解釋器里實時完成,讓讀者更清楚的看到十進(jìn)制和二進(jìn)制的相互轉(zhuǎn)換在Python中是怎樣完成的)大致可以歸納為A,B,C,D,E總共5個點,分述如下:

A.

我們知道任何一個合法的IP地址和子網(wǎng)掩碼都可以用32位的二進(jìn)制(binary)表示,這32位二進(jìn)制又被分為4個八位位組(octet),比如192.168.1.1用二進(jìn)制可以寫成11000000.10101000.00000001.00000001,這個轉(zhuǎn)換步驟在Python中實現(xiàn)的方法如下:

用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

  • 這里我們用字符串自帶的split()函數(shù)將ip地址(字符串‘192.168.1.1')轉(zhuǎn)換成列表ip_octets,然后創(chuàng)建一個空列表ip_octets_binary,隨后用for循環(huán)遍歷ip_octets里的元素,將它們每個用bin()函數(shù)轉(zhuǎn)換成二進(jìn)制形式,然后一一寫入剛才創(chuàng)建的空列表ip_octets_binary里面。
  • 關(guān)于binary_octet = bin(int(octet)).lstrip('0b'),bin()只能將數(shù)據(jù)類型為整數(shù)的十進(jìn)制數(shù)轉(zhuǎn)換成二進(jìn)制,因此這里我們要先將字符串用int()轉(zhuǎn)換成整數(shù)后再來調(diào)用bin()函數(shù),而bin()函數(shù)本身會在轉(zhuǎn)化后的二進(jìn)制數(shù)字前面加上'0b',我們必須調(diào)用lstrip('0b')將其拿掉,演示如下:
用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

  • 再來看ip_octets_binary.Append(binary_octet.zfill(8))中的zfill(8),它的作用是自動幫我們填充八位數(shù)的二進(jìn)制數(shù),什么意思呢?比如我們有個IP地址192.168.0.1,它的第三個八位組為0,寫成二進(jìn)制的話應(yīng)該為00000000,如果我們將0用bin()轉(zhuǎn)換成二進(jìn)制后會怎么樣呢?演示如下:
用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

是不是只得到了一位數(shù)的二進(jìn)制數(shù)0?加上zfill(8)后即得到八位組的二進(jìn)制00000000,效果如下:

用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

同樣的代碼也適用于子網(wǎng)掩碼,比如在Python中要將255.255.255.0這個掩碼轉(zhuǎn)換成二進(jìn)制形式,代碼可以這么寫:

用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

B.

知道如何在Python里將十進(jìn)制的IP地址和子網(wǎng)掩碼轉(zhuǎn)換成二進(jìn)制后,我們再來看下如何將二進(jìn)制的IP地址和子網(wǎng)掩碼轉(zhuǎn)換回十進(jìn)制(代碼接續(xù)前文):

用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

  • 這里只講一點,在Python中我們可以借助int()函數(shù)里的2這個參數(shù)將數(shù)據(jù)類型為字符串的二進(jìn)制數(shù)字轉(zhuǎn)換成數(shù)據(jù)類型為整數(shù)的十進(jìn)制數(shù)字,舉例如下:
用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

  • 同樣的道理,我們可以將二進(jìn)制形式的子網(wǎng)掩碼轉(zhuǎn)換回十進(jìn)制:
用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

C.

我們知道要算出一個網(wǎng)段內(nèi)有多少可用的IP地址需要知道該網(wǎng)段的子網(wǎng)掩碼以二進(jìn)制表達(dá)時里面有多少個0 (number of zeros,在Python中我們將其賦值給變量no_of_zeros),然后套用公式2 ** no_of_zeros - 2即可算出,比如這里給定的子網(wǎng)掩碼255.255.255.0,將其轉(zhuǎn)化為二進(jìn)制為1111111.1111111.11111111.00000000,總共8個0, 那么2**8-2 = 254,即為我們要的結(jié)果,這個運算過程在Python中的計算方式如下(代碼接前文):

用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

  • 這里我們用abs()這個絕對值函數(shù)來計算有多少可用的IP地址,原因是當(dāng)子網(wǎng)掩碼為/32 (255.255.255.255)時,no_of_zeros = 0,如果不用abs()的話, 2 ** 0 - 2 結(jié)果為負(fù)1,用abs()則可以將其轉(zhuǎn)換成正1, 演示如下:
用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

D.

我們知道網(wǎng)絡(luò)IP和廣播IP是兩個很重要的概念,在給定一個IP地址及其子網(wǎng)掩碼后,計算該網(wǎng)段的網(wǎng)絡(luò)IP和廣播IP的方法想必大家都知道,即將IP地址和子網(wǎng)掩碼分別轉(zhuǎn)換成二進(jìn)制,然后將兩者對比,看子網(wǎng)掩碼的二進(jìn)制有多少個1,那么IP地址的二進(jìn)制就從左至右保留多少位,剩下的部分全部以0填充,即可得到網(wǎng)絡(luò)IP的二進(jìn)制地址,如果剩下部分全部以1填充,則得到廣播IP的二進(jìn)制地址(這里就不畫圖演示了,這些都是網(wǎng)工最最最基礎(chǔ)的知識點,不懂的回去把CCENT或CCNA的書重新翻出來讀)。下面我們在Python中演示如何實現(xiàn)找出一個指定IP所在網(wǎng)段的網(wǎng)絡(luò)IP和廣播IP(代碼接前文,以前文給定的IP地址192.168.1.1和子網(wǎng)掩碼255.255.255.0為例):

用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

  • 在使用上面提到的填充0的方法得到了網(wǎng)絡(luò)IP的二進(jìn)制地址(11000000101010000000000100000000)后,為了將它轉(zhuǎn)換成四個八位組的十進(jìn)制形式,這里我們巧用for循環(huán)配合range(0,32,8)來將該網(wǎng)絡(luò)IP的二進(jìn)制地址切成四段,每段含8個二進(jìn)制數(shù)字,作為元素被依次添加進(jìn)net_ip_octets這個空列表,最后使用帶參數(shù)2的int()函數(shù)將它們轉(zhuǎn)換成十進(jìn)制,然后再將這四個十進(jìn)制數(shù)字作為元素依次添加進(jìn)net_ip_address這個空列表,最后配合".".join()將給列表轉(zhuǎn)化為字符串,即得到了網(wǎng)絡(luò)IP:192.168.1.0

依葫蘆畫瓢,從下面這段代碼中我們又得到了廣播IP: 192.168.1.255

用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

E.

最后我們來談?wù)劮囱诖a,所謂反掩碼就是將子網(wǎng)掩碼的二進(jìn)制里的1換成0,將0換成1,比如255.255.255.0的二進(jìn)制為11111111.11111111.11111111.00000000,它的反掩碼即為00000000.00000000.00000000.11111111,也就是0.0.0.255。在Python里我們可以這樣表示(代碼接上文):

用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

最后來看下該交互式的網(wǎng)絡(luò)和IP地址計算器的最終代碼:

#coding=utf-8
import sys
try:    while True: #判斷用戶輸入的IP是否符合規(guī)范,如果不規(guī)范則while循環(huán)反復(fù)詢問,直到用戶輸入正確IP地址為止。        ip_address = input("輸入要查詢的IP地址: ")          
        ip_octets = ip_address.split('.') #將IP地址用split()轉(zhuǎn)換成列表,該列表有4個元素,分別代表用戶輸入的IP地址的4個8位字段。
        #0.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16以及Class D這些保留IP地址均不是有效的IP
        if (len(ip_octets) == 4) and (1 <= int(ip_octets[0]) <= 223) and (int(ip_octets[0]) != 127) and (int(ip_octets[0]) != 169 or int(ip_octets[1]) != 254) and (0 <= int(ip_octets[1]) <= 255 and 0 <= int(ip_octets[2]) <= 255 and 0 <= int(ip_octets[3]) <= 255):
            break
        else:
            print("n不是有效的IP地址,請重新輸入n")
            continue
    masks = [255, 254, 252, 248, 240, 224, 192, 128, 0] #將所有有效的子網(wǎng)掩碼的十進(jìn)制數(shù)字歸納進(jìn)一個列表,用于驗證用戶輸入的子網(wǎng)掩碼是否合乎規(guī)范
    while True: #判斷用戶輸入的子網(wǎng)掩碼是否符合規(guī)范,如果不規(guī)范則while循環(huán)反復(fù)詢問,直到用戶輸入正確子網(wǎng)掩碼為止。        subnet_mask = input("輸入子網(wǎng)掩碼: ")        
        mask_octets = subnet_mask.split('.') #將子網(wǎng)掩碼用split()轉(zhuǎn)換成列表,該列表有4個元素,分別代表用戶輸入的子網(wǎng)掩碼的4個8位字段。
        #支持/0 - /32所有子網(wǎng)掩碼
        if (len(mask_octets) == 4) and (int(mask_octets[0]) in masks) and (int(mask_octets[1]) in masks) and (int(mask_octets[2]) in masks) and (int(mask_octets[3]) in masks) and (int(mask_octets[0]) >= int(mask_octets[1]) >= int(mask_octets[2]) >= int(mask_octets[3])):
            break
        else:
            print("n不是有效的子網(wǎng)掩碼,請重新輸入n")
            continue
    mask_octets_binary = []    for octet in mask_octets:
        binary_octet = bin(int(octet)).lstrip('0b')
        #print(binary_octet)
        mask_octets_binary.append(binary_octet.zfill(8))
    #print(mask_octets_binary)
    binary_mask = "".join(mask_octets_binary)
    #print(decimal_mask)   
    no_of_zeros = binary_mask.count("0")
    no_of_ones = 32 - no_of_zeros
    no_of_hosts = abs(2 ** no_of_zeros - 2) #當(dāng)掩碼為/32時,2的0次方減1等于-1,需要用abs()函數(shù)將其轉(zhuǎn)換成正數(shù)1.
    #print(no_of_zeros)
    #print(no_of_ones)
    #print(no_of_hosts)
    wildcard_octets = []    for octet in mask_octets:
        wild_octet = 255 - int(octet)
        wildcard_octets.append(str(wild_octet))
    #print(wildcard_octets)
    wildcard_mask = ".".join(wildcard_octets)
    #print(wildcard_mask)
    ip_octets_binary = []    for octet in ip_octets:
        binary_octet = bin(int(octet)).lstrip('0b')
        #print(binary_octet)
        ip_octets_binary.append(binary_octet.zfill(8))
    #print(ip_octets_binary)
    binary_ip = "".join(ip_octets_binary)
    #print(binary_ip)   
    network_address_binary = binary_ip[:(no_of_ones)] + "0" * no_of_zeros
    #print(network_address_binary)
    broadcast_address_binary = binary_ip[:(no_of_ones)] + "1" * no_of_zeros
    #print(broadcast_address_binary)
    net_ip_octets = []    for bit in range(0, 32, 8):
        net_ip_octet = network_address_binary[bit: bit + 8]
        net_ip_octets.append(net_ip_octet)
    #print(net_ip_octets)
    net_ip_address = []    for each_octet in net_ip_octets:
        net_ip_address.append(str(int(each_octet, 2)))
    #print(net_ip_address)
    network_address = ".".join(net_ip_address)
    #print(network_address)
    bst_ip_octets = []    for bit in range(0, 32, 8):
        bst_ip_octet = broadcast_address_binary[bit: bit + 8]
        bst_ip_octets.append(bst_ip_octet)
    #print(bst_ip_octets)
    bst_ip_address = []    for each_octet in bst_ip_octets:
        bst_ip_address.append(str(int(each_octet, 2)))
    #print(bst_ip_address)
    broadcast_address = ".".join(bst_ip_address)
    #print(broadcast_address)
        print("n")
    print("該網(wǎng)段的網(wǎng)絡(luò)地址為: %s" % network_address)
    print("該網(wǎng)段的廣播地址為: %s" % broadcast_address)
    print("該網(wǎng)段可用的IP地址數(shù)量為: %s" % no_of_hosts)
    print("反掩碼: %s" % wildcard_mask)
    print("掩碼位: %s" % no_of_ones)
    print("n")
    print(input())
except KeyboardInterrupt:    print("nn程序終止n")
    sys.exit()
  • 代碼前面用來判斷用戶所輸入的IP地址和子網(wǎng)掩碼是否合法的部分,我已經(jīng)在相應(yīng)位置做了備注幫助大家理解,這里就不再贅述了。

最后運行該程序看效果:

用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 


用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 


用Python開發(fā)一個交互式網(wǎng)絡(luò)和IP地址計算器

 

分享到:
標(biāo)簽:地址 IP
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達(dá)人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定