前言
最近在工作中需要對用戶輸入的ip進行重復(fù)性校驗纲缓,之前處理的都是單ip,直接通過ip字符串比較即可。現(xiàn)在用戶輸入的是ip+掩碼的方式,也就是支持ip范圍輸入夯缺,這樣之前的校驗方式就行不通了。
說明
那么如何解決呢代赁?我們都知道ip4是通過"點分十進制"來表示的扰她,本質(zhì)上就是一個二進制的整數(shù),只需要將十進制的表示的IP轉(zhuǎn)換為二進制整數(shù)芭碍,通過數(shù)值進行比較即可徒役。
對于單ip而言,直接轉(zhuǎn)換為整數(shù)窖壕,對于ip+掩碼的形式(也就是ip范圍)獲取范圍的開始值和結(jié)束值就可以確定其范圍了忧勿。
這里介紹如下:
- 1.單ip轉(zhuǎn)換為整數(shù)
- 2.ip+掩碼形式的IP段,獲取開始和結(jié)束ip
單個ip轉(zhuǎn)換為整數(shù)
# ip4轉(zhuǎn)換為int類型
ip4_to_int = lambda ip: sum([256 ** j * int(i) for j, i in enumerate(ip.split('.')[::-1])])
ip+掩碼形式的ip獲取起始范圍
1.原理(以192.168.1.53/27為例)
192.168.1.53的二進制表示 | 11000000.10101000.00000001.00110101 | |
---|---|---|
子網(wǎng)掩碼 | 11111111.11111111.11111111.11100000 | 27表示有27個1 |
網(wǎng)絡(luò)地址 | 11000000.10101000.00000001.00100000 | 子網(wǎng)掩碼與ip地址進行與運算瞻讽,得到網(wǎng)絡(luò)地址(與運算就是全1為1鸳吸,其它都為0) |
廣播地址 | 11000000.10101000.00000001.00111111 | 在網(wǎng)絡(luò)地址的基礎(chǔ)上,將主機地址全部填充為1 |
其中網(wǎng)路地址就是ip段的開始值速勇,廣播地址就是ip段的結(jié)束值.
2.具體代碼實現(xiàn)
def get_ip_mask_range(ip, mask):
"""獲取掩碼ip的整數(shù)范圍(包括網(wǎng)絡(luò)地址和廣播地址)"""
# ip4轉(zhuǎn)換為int類型
ip4_to_int = lambda ip: sum([256 ** j * int(i) for j, i in enumerate(ip.split('.')[::-1])])
if mask:
# 子網(wǎng)掩碼
sub_mask = '0b{0:0<32}'.format(int("".join(['1' for i in range(mask)])))
# 網(wǎng)絡(luò)地址
network = ip4_to_int(ip) & int(sub_mask, 2) # 與運算晌砾,獲取網(wǎng)絡(luò)地址
# 主機地址
host = '0b{0:0>32}'.format(int("".join(['1' for i in range(32 - mask)])))
print(host)
# 廣播地址
broad = network | int(host, 2) # 或運算,將主機號置為1
print("network:{}, broad:{}".format(network, broad))
start_ip_int, end_ip_int = network, broad
else:
start_ip_int = end_ip_int = ip4_to_int(ip)
return start_ip_int, end_ip_int
喜歡點個贊7炒拧Q佟!