题解 | 识别有效的IP地址和掩码并进行分类统计
识别有效的IP地址和掩码并进行分类统计
https://www.nowcoder.com/practice/de538edd6f7e4bc3a5689723a7435682
import sys
def check_ip(ip_str):
# 检查ip地址是否合法
ip_data = ip_str.split(".")
#是否是四位
if len(ip_data) !=4:
return False, []
nums = []
for part in ip_data:
# 是否存在空段 10.0..1
if not part:
return False, []
# 是否是数字
if not part.isdigit():
return False, []
num = int(part)
# 是否超过范围
if num < 0 or num > 255:
return False, []
nums.append(num)
return True, nums
def check_mask(mask__str):
# 是否合法子网掩码
valid, nums = check_ip(mask__str)
if not valid:
return False
# 转换成二进制
bin_str = ''
for num in nums:
# 十进制转成二进制,并填充到8位
bin_str = bin_str + bin(num)[2:].zfill(8)
# 检查是否全部为1或全部为0
if bin_str.count("1") == 32 or bin_str.count("0")==32:
return False
# 检查是否连续1后接连续0
found_zero = False
for i in range(32):
if bin_str[i] == '0':
found_zero = True
elif found_zero and bin_str[i] == '1':
return False
return True
def classify_ip(ip_nums):
first_num = ip_nums[0]
second_num = ip_nums[1]
mark = None
if 1 <= first_num <= 127:
mark = "A"
elif 128 <= first_num <= 191:
mark = "B"
elif 192 <= first_num <= 223:
mark = "C"
elif 224 <= first_num <= 239:
mark = "D"
elif 240 <= first_num <= 255:
mark = "E"
# 是否私有IP
is_private = False
if first_num == 10:
is_private = True
elif first_num == 172 and 16 <= second_num <= 31:
is_private = True
elif first_num == 192 and second_num == 168:
is_private = True
return mark, is_private
def run():
# 一次性读取所有的输入,按照行切割
data = sys.stdin.read().split("\n")
# 剔除最后一个空行
new_data = data[0:-1]
# 定义一个存储器
result = {"A":0, "B":0, "C":0, "D":0, "E":0, "error":0, "prv":0}
# 逐行处理
for line in new_data:
# 判断输入是否合法
if line.count("~") != 1:
result["error"] = result["error"] + 1
continue
# 分割IP和mask
ip_str, mask__str = line.split("~")
# 检查是否为特殊IP(0.*.*.*或127.*.*.*)
if ip_str.startswith('0.') or ip_str.startswith('127.'):
# 进一步验证格式
valid, ip_nums = check_ip(ip_str)
if valid and (ip_nums[0] == 0 or ip_nums[0] == 127):
# 特殊IP,直接跳过,不计入任何统计
continue
# 验证IP地址有效
ip_valid, ip_nums = check_ip(ip_str)
if not ip_valid:
result['error'] += 1
continue
# 验证mask掩码的有效性
mask_valid = check_mask(mask__str)
if not mask_valid:
result['error'] += 1
continue
# 分类统计
mark, is_private = classify_ip(ip_nums)
if mark:
result[mark] += 1
if is_private:
result["prv"] += 1
print(result["A"], result["B"], result["C"], result["D"], result["E"], result["error"], result["prv"])
run()
核心步骤
- 读取输入:使用 sys.stdin一直读取到文件结尾
- 解析每一行:分割 IP 地址和子网掩码
- 检查特殊 IP:跳过 0...* 和 127...*
- 验证格式和范围:检查 IP 和掩码格式是否合法
- 验证子网掩码:转换为二进制,检查是否符合连续1+连续0的规则
- 分类统计: 如果不合法,错误计数加1 如果合法,判断类别和是否为私有IP
关键细节
- IP地址格式验证: 必须是四段数字 每段必须是0-255的整数 不能有空段(如"10..1.1")
- 子网掩码验证: 先转换为32位二进制字符串 必须满足连续1后接连续0 不能全1或全0
- 特殊处理: 0...* 和 127...* 不参与任何统计(包括错误统计)

