测试以查看IPv4地址是否有效

时间:2016-10-26 19:51:54

标签: python iterable built-in

我想返回一个布尔值,具体取决于给定的地址是否是正确的IPv4地址。我遇到了python中内置的all()问题。我查阅了它的文档,看起来很简单。话虽如此,我无法让它为我的表达而工作。如果你可以解释它是如何工作的外行人的术语以及我如何纠正我的代码,那就太棒了。

def IPv4_address(address):

    lst_split_address = address.split(".")
    slice_split_address = [int(num) for num in lst_split_address[1:]]

    if address.count(".") != 3:
        return False
    elif address == "":
        return False
    else:
        if all(slice_split_address) >= slice_split_address[0]:
            return True
        else:
            return False


print IPv4_address("10.20.30.40")

4 个答案:

答案 0 :(得分:1)

不要重新发明轮子(除非你乐意维护轮子)。您可以使用正则表达式来验证ipv4地址。以下模式为taken from Django

r'(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}'

如果您已经在Django项目的上下文中工作,您可能更愿意只导入他们的验证器并直接使用它:

from django.core.validators import validate_ipv4_address

答案 1 :(得分:1)

如果您使用的是Python3,则可以使用内置的ipaddress模块。

至于你的代码有什么问题,我不相信all()函数会按照你的想法做到。 all()需要一个可迭代的布尔值,如果每个布尔值都是True,则返回True

为了让你按照预期工作,你可能需要像

这样的东西
all(addr_piece >= slice_split_address[0] for addr_piece in slice_split_address)

答案 2 :(得分:1)

all的文档中所述,它检查列表中的每个元素是否评估为True(基本上bool(e)True)还是空的。< / p>

现在你在slice_split_address中有一个整数列表,所以它会检查该列表的每个元素是否评估为True,如果你只是像你那样调用它,除了True以外的任何数字0将评估为127.0.0.1,但像True这样的IP实际上是有效的。

所以你需要的是一个包含is_valid = [0 <= e <= 255 for e in slice_split_address] 的列表,如果相应的数字在0到255之间(包括):

all(is_valid)

如果您致电slice_split_address,则all(0 <= e <= 255 for e in slice_split_address)中的每个项目都介于0到255之间。通常会将其合并为slice_split_address

现在您的实施中仍然存在一个问题,因为all(…) >= …实际上并不包含IP地址的第一个数字,因此您可以包含它。或者你真的希望第一个数字低于或等于其他三个数字吗?

另外,您的支票all()没有意义,因为True仅返回Falseall(is_valid),因此将其与整数进行比较并不能确定感。

请注意,True也会将0.0.0.0返回到{{1}}等IP地址,因此可能需要调整我使用的范围。

答案 3 :(得分:0)

正如其他人所说,有更好的方法可以做到这一点。并且您的算法实际上并不验证IPv4地址。但这是修复后的代码版本。

def IPv4_address(address):
    if address.count(".") != 3:
        return False
    elif address == "":
        return False
    else:
        lst_split_address = address.split(".")
        slice_split_address = [int(num) for num in lst_split_address[1:]]
        head = slice_split_address[0]
        return all(u >= head for u in slice_split_address)

print IPv4_address("10.20.30.40")

<强>输出

True

我已将lst_split_address内容移动到else块中,因为如果if / elif部分返回False,则无需执行此操作。

all(u >= head for u in slice_split_address)

使用简单的生成器表达式检查slice_split_address中的所有项目是&gt; =头部项目。