啥都不说了,直接上代码
def invert_bin_str(bin_str):
"""
二进制字符串按位取反
如:'10001011' => '01110100'
:param bin_str: 二进制字符串 如:'10001011' (str)
:return: 按位置反后的二进制字符串 如:'01110100' (str)
"""
# 创建一个空白的转换后的字符串变量
inverted_bin_str = ''
# 循环判断原始二进制字符串中的每一位,若为'1'就转换成'0',若为'0'就转换成'1',
# 然后添加到inverted_bin_str中
for i in bin_str:
if i == '1':
inverted_bin_str += '0'
else:
inverted_bin_str += '1'
return inverted_bin_str
def or_bin_str(bin_str_a, bin_str_b):
"""
将二进制字符串按位或运算
:param bin_str_a: 准备或运算的二进制字符串a 如:'10001011' (str)
:param bin_str_b: 准备或运算的二进制字符串b 如:'11111100' (str)
:return: 两个二进制或运算之后的值 如:'11111111' (str)
"""
# 先获取两个二进制字符串的长度
bin_str_a_len, bin_str_b_len = len(bin_str_a), len(bin_str_b)
# 判断两个二进制字符串的长度是否一致
if bin_str_a_len != bin_str_b_len:
raise Exception('进行或运算的两个二进制字符串长度不一致')
else:
bin_str_len = bin_str_a_len
# 两个二进制字符串按位置反运算
new_bin_str = ''
for i in range(0, bin_str_len):
if int(bin_str_a[i], 2) + int(bin_str_b[i], 2) >= 1:
new_bin_str += '1'
else:
new_bin_str += '0'
return new_bin_str
def get_broadcast_with_ip_and_netmask(ip, netmask):
"""
使用IP地址和子网掩码计算获取广播地址
:param ip: IP地址 如:'192.168.4.1'(str)
:param netmask: 子网掩码 如:'255.255.255.0'(str)
:return: 局域网内的广播地址 如:'192.168.4.255' (str)
"""
"""
处理IP地址
ip_segment_list ['192', '168', '4', '1']
bin_str_ip_segment_list ['11000000', '10101000', '00000100', '00000001']
bin_str_ip '11000000101010000000010000000001'
int_ip 3232236545
"""
# 1.先拆分IP地址成列表['192', '168', '1', '1']
ip_segment_list = ip.split('.')
# 2.转成二进制字符串列表['11000000', '10101000', '00000001', '00000001']
bin_str_ip_segment_list = []
for ip_segment in ip_segment_list:
bin_str_ip_segment = bin(int(ip_segment))[2:]
while True:
if len(bin_str_ip_segment) <= 7:
bin_str_ip_segment = '0' + bin_str_ip_segment
else:
break
bin_str_ip_segment_list.append(bin_str_ip_segment)
# 3.合并成二进制字符串'11000000101010000000000100000001'
bin_str_ip = ''.join(bin_str_ip_segment_list)
# 4. 转换成整数3232235777
int_ip = int(bin_str_ip, 2)
# print('{} / {} / {} / {}'.format(ip_segment_list,bin_str_ip_segment_list, bin_str_ip, int_ip))
"""
处理子网掩码
netmask_segment_list ['255', '255', '255', '0']
bin_str_netmask_segment_list ['11111111', '11111111', '11111111', '00000000']
bin_str_netmask '11111111111111111111111100000000'
int_netmask 4294967040
"""
# 1.先拆分子网掩码地址成列表['255', '255', '255', '0']
netmask_segment_list = netmask.split('.')
# 2.转成二进制字符串列表['11111111', '11111111', '11111111', '00000000']
bin_str_netmask_segment_list = []
for netmask_segment in netmask_segment_list:
bin_str_netmask_segment = bin(int(netmask_segment))[2:]
while True:
if len(bin_str_netmask_segment) <= 7:
bin_str_netmask_segment = '0' + bin_str_netmask_segment
else:
break
bin_str_netmask_segment_list.append(bin_str_netmask_segment)
# 3.合并成二进制字符串'11111111111111111111111100000000'
bin_str_netmask = ''.join(bin_str_netmask_segment_list)
# 4.转换成整数4294967040
int_netmask = int(bin_str_netmask, 2)
# print('{} / {} / {} / {}'.format(netmask_segment_list, bin_str_netmask_segment_list, bin_str_netmask, int_netmask))
"""
获取网络地址
int_network 3232235776
bin_str_network '11000000 10101000 00000001 00000000'
"""
# 网络地址只需要将IP地址和子网掩码进行“与”运算
int_network = int_ip & int_netmask
bin_str_network = bin(int_network)[2:]
"""
获取广播地址
inverted_bin_str_netmask '00000000000000000000000011111111'
bin_str_broadcast '11000000101010000000010011111111'
broadcast_segment_list ['192', '168', '4', '255']
broadcast '192.168.4.255'
"""
# 将子网掩码按位取反
inverted_bin_str_netmask = invert_bin_str(bin_str_netmask)
# 将取反后的子网掩码与网络地址进行或运算
bin_str_broadcast = or_bin_str(inverted_bin_str_netmask, bin_str_network)
broadcast_segment_list = [
str(int(bin_str_broadcast[0:8], 2)),
str(int(bin_str_broadcast[8:16], 2)),
str(int(bin_str_broadcast[16:24], 2)),
str(int(bin_str_broadcast[24:32], 2))
]
bs_1, bs_2, bs_3, bs_4 = broadcast_segment_list
broadcast = "{}.{}.{}.{}".format(bs_1, bs_2, bs_3, bs_4)
return broadcast
if __name__ == '__main__':
print('根据IP地址和子网掩码获取的广播地址:' + get_broadcast_with_ip_and_netmask('192.168.4.1', '255.255.255.0'))