这是一篇解析编程练习网站LeeCode上面的一道题的文章。 题目地址:力扣 分为几步:

  • 题目内容
  • 官方示例
  • 思路解析和 解题方法

题目内容

  1. 验证IP地址

编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址。

IPv4 地址由十进制数和点来表示,每个地址包含4个十进制数,其范围为 0 - 255, 用(".")分割。比如,172.16.254.1; 同时,IPv4 地址内的数不会以 0 开头。比如,地址 172.16.254.01 是不合法的。

IPv6 地址由8组16进制的数字来表示,每组表示 16 比特。这些组数字通过 (":")分割。比如,  2001:0db8:85a3:0000:0000:8a2e:0370:7334 是一个有效的地址。而且,我们可以加入一些以 0 开头的数字,字母可以使用大写,也可以是小写。所以, 2001:db8:85a3:0:0:8A2E:0370:7334 也是一个有效的 IPv6 address地址 (即,忽略 0 开头,忽略大小写)。

然而,我们不能因为某个组的值为 0,而使用一个空的组,以至于出现 (::) 的情况。 比如, 2001:0db8:85a3::8A2E:0370:7334 是无效的 IPv6 地址。

同时,在 IPv6 地址中,多余的 0 也是不被允许的。比如, 02001:0db8:85a3:0000:0000:8a2e:0370:7334 是无效的。

说明: 你可以认为给定的字符串里没有空格或者其他特殊字符。

官方示例

示例1

输入: “172.16.254.1”

输出: “IPv4”

解释: 这是一个有效的 IPv4 地址, 所以返回 “IPv4”。

示例2

输入: “2001:0db8:85a3:0:0:8A2E:0370:7334”

输出: “IPv6”

解释: 这是一个有效的 IPv6 地址, 所以返回 “IPv6”。

示例3

输入: “256.256.256.256”

输出: “Neither”

解释: 这个地址既不是 IPv4 也不是 IPv6 地址。

思路解析和 解题方法

最直接的方法是直接调用Python 中的跟ip地址相关的包:ipaddress 它是专门用来处理ipv4和ipv6相关的包,像这种/24生成子网ip地址之类的非常方便。而题目要求就是判断是不是有效的ipv4或者ipv6,那么ipaddress.ip_address就可以很方便地解决这个问题了。请看官方说明

'''
ipaddress.ip_address(address)
Return an IPv4Address or IPv6Address object depending on the IP address passed as argument. Either IPv4 or IPv6 addresses may be supplied; integers less than 2**32 will be considered to be IPv4 by default. A ValueError is raised if address does not represent a valid IPv4 or IPv6 address.
简单讲就是:
通过一个ip地址将会返回一个ipv4或者ipv6的对象,如果不是有效地址将会生成一个valueerror。
>>>
ipaddress.ip_address('192.168.0.1')
IPv4Address('192.168.0.1')
ipaddress.ip_address('2001:db8::')
IPv6Address('2001:db8::')

'''

那么判断代码也就清楚了

import ipaddress

class Solution:
    def validIPAddress(self, IP: str) -> str:
        try:
            addtype = type(IP)
            if addtype == ipaddress.IPv4Address:
                return "IPv4"
            return "IPv6"

        except ValueError:
            return "Neither"

但是在实际运行中提交发生错误,这是由于"01.01.01.01"的地址被认为是合法的ipv4,而在题目中却规定不能有0

“IPv4 地址内的数不会以 0 开头”

因此我们应该首先把ip地址分段在组合成新的数组,最后交给ipaddress包处理就可以了。

且看代码:



import ipaddress

class Solution:
    def validIPAddress(self, IP: str) -> str:

        try:
            addtype = type(ipaddress.ip_address(IP))
            if addtype == ipaddress.IPv4Address:
                for little in IP.split("."):
                    if len(little)>1 and "0" == little[0]:
                        return "Neither"
                return "IPv4"
            IP = IP.split(":")
            
            for little in IP:
                if len(little)>4 or little=='':
                    return "Neither"
            return "IPv6"

        except ValueError:
            return "Neither"


        
        

经过n次调试后,上述代码终于可以通过了。。。

运行时间40ms,内存消耗13.9MB

总结

实际情况本来是ipaddress包就可以解决的,但是在题目中引入了很多的限制条件,无形中增加了很多的麻烦,不过只需要根据提交测试的错误结果一步步改正就可以了。 另外大家也可以好好学习下ipaddress包,在处理网络地址方面的问题上真的很方便的。