CS50 Python任务中IPv4地址验证函数因仅检测第一个字节范围导致测试失败的问题求助
CS50 Python任务中IPv4地址验证函数因仅检测第一个字节范围导致测试失败的问题求助
我正在做CS50 Python的numb3rs任务,需要写一个验证IPv4地址的函数,要求格式为X.X.X.X且每个X在0-255之间,合法返回True否则返回False。但check50测试失败,错误提示我的代码只检查了第一个字节的范围,我不太明白问题出在哪。
以下是我的相关代码和问题细节:
错误信息
:( test_numb3rs.py catches numb3rs.py only checking if first byte of IPv4 address is in range
主代码(numb3rs.py)
import re def main(): print(validate(input("IPv4 Address: "))) def validate(ip): match = re.fullmatch(r"(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})", ip) return bool(match) and all(0 <= int(octet) <= 255 for octet in match.groups()) if __name__ == "__main__": main()
测试代码(test_numb3rs.py)
from numb3rs import validate def test_validate(): # Valid cases assert validate("127.0.0.1") == True assert validate("255.255.255.255") == True # Invalid cases assert validate("512.512.512.512") == False assert validate("1.2.3.1000") == False assert validate("cat") == False
问题分析与解决思路
你的代码实际上已经正确检查了所有四个字节的范围,check50的错误提示可能存在误导性,或者是因为你的代码遗漏了CS50任务中的另一个关键规则:IPv4地址的每个字节不能有前导零(除非该字节本身就是0)。
比如,你的代码会认为01.0.0.1是合法的,但根据CS50的要求,这种带前导零的地址是无效的,这很可能是导致check50测试失败的真正原因。
修复方案
你可以通过两种方式修复这个问题:
方案1:修改正则表达式,直接排除前导零
更新正则表达式,确保每个字节要么是0,要么是没有前导零的1-3位有效数字:
import re def main(): print(validate(input("IPv4 Address: "))) def validate(ip): # 正则表达式匹配合法的IPv4字节:无前置零且在0-255之间 octet_pattern = r"(0|([1-9]\d{0,1})|1\d{2}|2[0-4]\d|25[0-5])" match = re.fullmatch(rf"{octet_pattern}\.{octet_pattern}\.{octet_pattern}\.{octet_pattern}", ip) return bool(match) if __name__ == "__main__": main()
方案2:保留原正则,添加前导零检查
在原有的范围检查基础上,增加对前导零的判断:
import re def main(): print(validate(input("IPv4 Address: "))) def validate(ip): match = re.fullmatch(r"(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})", ip) if not match: return False # 检查每个字节:范围合法 + 无前置零(除非是0本身) for octet in match.groups(): if len(octet) > 1 and octet.startswith('0'): return False if not (0 <= int(octet) <= 255): return False return True if __name__ == "__main__": main()
补充测试用例
建议在你的测试代码中添加前导零相关的测试用例,确保覆盖所有场景:
from numb3rs import validate def test_validate(): # Valid cases assert validate("127.0.0.1") == True assert validate("255.255.255.255") == True assert validate("0.0.0.0") == True # Invalid cases assert validate("512.512.512.512") == False assert validate("1.2.3.1000") == False assert validate("cat") == False # 新增前导零测试 assert validate("01.0.0.1") == False assert validate("127.01.0.1") == False assert validate("000.0.0.1") == False
备注:内容来源于stack exchange,提问作者Rubab Khaskheli
相关产品推荐
相关产品推荐

