其他分享
首页 > 其他分享> > 计算机网络:判断输入字符串是否是合法的IP地址

计算机网络:判断输入字符串是否是合法的IP地址

作者:互联网

一、题目要求

请创作一个小程序,实现如下功能:
1.判断输入的字符串是否是合法的IP地址
2.如果是合法的IP地址表达,请判断是v4还是v6地址,并将其展开为对应的2进制串输出
3.如果不是合法的IP地址表达,判断输入的字符串是否是合法的地址范围表达式,如"192.168.0.0/24"、“::1/128”
4.如果是合法的地址范围表达式,输出其最小和最大地址,以及地址总数
5.如果既不是合法的IP地址也不是合法的地址范围表达式,输出“不合法”

二、前期思路

在这里插入图片描述

        根据题目我先做了上面的一个伪代码表示过程。接下来我要做的是思考如何区分是否是一个地址还是一个地址范围。仔细观察我们可以看到一个地址和一个范围最大的区别就是后面的子网掩码位数和斜杠,所以我这里想把斜杠作为一个标志符来区分地址和地址范围。
        关于地址的合法判断,如果是ipv4,则可以按照’.’将地址分为4个部分,检测每个部分是否大于255,不然可以视为合法地址。如果是ipv6还要考虑缩写的问题,这里思路应该是先检测地址的位数是否合理(是否是完全展开的形式),如果不是的话则要扩充到完全展开的形式,然后再进行判断。合法地址的二进制形式可以先将地址按照’.’或者’:’进行分割,然后再把每个部分从string转成int再进行转换操作。
        关于地址范围的判断,我的想法是先看看有没有斜杠,如果有的话就把地址范围分成两个部分:前面的网段和后面的子网掩码位数。题目的要求是输出最大地址和最小地址,并且输出总数,总数这里可以根据子网掩码去判断。2的32-子网掩码或者128-子网掩码次方再减去2,因为第一个最后一位是0那个地址和最后那个广播地址是不可用的,这里两个地址应当判断为不合法的地址。最小地址应该是网段那串数字加1,最大的地址应当是广播地址-1,这样子就可以得出题目所需要的东西了。

三、代码

import IPy

def tobin(ip):
    print('二进制格式转换:', IPy.IP(ip).strBin())

def jugiptype(ip):
    iptype = 0
    try:
        iptype = IPy.IP(ip).version()
    except:
        iptype = 0
    else:
        return iptype

def checkipv4oripv6(ip):
    if '/' not in ip:
        iptype = jugiptype(ip)
        if iptype:
            print ('iptype:',iptype)
            tobin(ip)
        else:
            print('ileagal address')

def checkipv4oripv6range(ip):
    if '/' in ip:
        try:
            ip1 = IPy.IP(ip)
        except:
            print('ileagal address')
            return
        depart = ip.split('/',1)
        jug1 = depart[1].isdigit()
        if jug1:
            Subnetmask = int(depart[1])
            iptype = jugiptype(depart[0])
            if iptype == 4 and Subnetmask <= 32:
                try:
                    print('totle address:', IPy.IP(ip).len()-2)
                except:
                    print ('ileagal address')
                x = IPy.IP(ip).strNormal(3).split('-', 1)
                y0,y1 = list(x[0]),list(x[1])
                y0[-1] = '1'
                minaddr = ''.join(y0)
                if y1[-1] != '0':
                    y1[-1] = str(int(y1[-1])-1)
                maxaddr = ''.join(y1)
                print('minaddr:',minaddr)
                print('maxaddr:',maxaddr)
            elif iptype == 6 and Subnetmask <= 128:
                try:
                    print ('totle address:',IPy.IP(ip).len()-2)
                except:
                    print ('ileagal address')
                x = IPy.IP(ip).strNormal(3).split('-',1)
                y0, y1 = list(x[0]), list(x[1])
                y0[-1] = '1'
                minaddr = ''.join(y0)
                if y1[-1] != '0':
                    y1[-1] = str(int(y1[-1]) - 1)
                maxaddr = ''.join(y1)
                print('minaddr:', minaddr)
                print('maxaddr:', maxaddr)
            else:
                print ('ileagal address')
        else:
            print ('ileagal address')

if __name__ == '__main__':
    ip = input()
    checkipv4oripv6(ip)
    checkipv4oripv6range(ip)

这里我使用的是python的IPy模块,这个模块里面的一些方法很适合这个题目的算法。参考以下地址

https://blog.csdn.net/xixihahalelehehe/article/details/105203978

        这个代码最主要的函数就是checkipv4oripv6函数和checkipv4oripv6range函数,用于区分地址范围还是地址。我这里的处理是两个函数一开始就让他判断是否有’/’,这样下面调用这两个函数的时候就只会挑一个进行了。
checkipv4oripv6(ip)中(ip):IPy.IP(ip).version()这个方法是用于判断是ipv4地址还是ipv6地址的,但是当出错的时候他这个函数的设定不是返回-1,而是会出错,所以我这里将他用一个try函数去执行,并且设定一个flag(iptype)去判断这个函数是否执行成功,如果成功这个值会是4或者6,否则是0。当他不合法的时候直接打印“ileagal”。如果是合法的则调用IPy.IP(ip).strBin()
函数将二进制打印出来。这部分就这样子完成了。
        checkipv4oripv6range(ip)中依旧是先判断’/’,一开始先执行一下ip1 = IPy.IP(ip)
因为如果这个执行失败的话就说明这个东西的不合法的(网段号最后一位不是0这种情况会报错)。所以可以根据这个来判断是否一开始这个网段号就写错了。然后就是使用IPy.IP(ip).len()去判断长度。不过这个函数的思路是有点问题的,因为如果直接打印ip1 = IPy.IP(ip)这个值的话(比如192.168.0.0/24)会从192.168.0.0这个开始打印,也就是这个函数认为192.168.0.0也是合法地址。包括最后那个广播地址也会打印出来。所以IPy.IP(ip).len()的结果是256,可以看到最后代码里做了-2处理。IPy.IP(ip).strNormal(3)
        函数本来是直接确定了最大最小地址的。但是这个是从0开始255结束的。但我们要去把头加1,最后那个-1,所以我调用完这个函数之后对数据进行了改动得到正确结果

四、测试样例

在这里插入图片描述
最后那个是256不合法
在这里插入图片描述
lh是不合法的
在这里插入图片描述
合法地址
在这里插入图片描述
合法地址
在这里插入图片描述
合法地址
在这里插入图片描述
子网掩码不合法
在这里插入图片描述
前面不是网段,我这里将他判定不合法
在这里插入图片描述
双冒号不合法的写法
在这里插入图片描述
这个更不合法了
在这里插入图片描述
合法地址

五、总结

     其实这一次算是真正的第一次用python去实现功能。其中有很多东西都是一边百度一边写的代码。刚刚开始我还头疼,因为如果按照以前c++的思维的话全部功能我都要自己去实现一遍,这个工程量我觉得还是有点大的。结果IPy模块的函数让我欣喜。这里面的函数虽然没有全部期望的功能,但是也算是把大量工作做了七八成了,所以整体做起来还算快。也深入了解了python的代码风格。
     期间还学到了一些不一样,例如:Python中string是不可变的,要把string变成list才能更改。Python的函数很多,写代码很方便。缩进很严谨。有其他语言编程基础很容易上手这门语言。ipv4和ipv6之间的区别,虽然还有些地方没有搞得太清楚,但总体上有了一点了解。
     其实这个IPy里面的函数跟我们预期有很多不一样的,比如数量那个函数没有剔除首尾两个地址,而且那个判定ipv4的函数也是有bug的,输入1234这样的数据的时候他会自动填充前面的0如下图:
在这里插入图片描述
IETF规范里面的特殊一点的样例也没有太多考虑,不过要加也是可以增加上去的,就是加大点工作量而已

六、参考文献

1.https://www.zhihu.com/question/361759837/answer/941637125

2.https://blog.csdn.net/gatieme/article/details/50989257utm_medium=distribute.pc_relevant_bbs_down.none-task–2allfirst_rank_v2rank_v29-2.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task–2allfirst_rank_v2rank_v29-2.nonecase

3.https://www.runoob.com/python/python-exceptions.html

4.https://blog.csdn.net/xixihahalelehehe/article/details/105203978

5.http://www.360doc.com/content/19/0809/12/29215996_853855203.shtml

6.计算机网络自顶向下第七版

7.https://baike.baidu.com/item/IPv4/422599?fr=aladdin

8.https://www.runoob.com/python3/python3-tutorial.html

9.https://baike.baidu.com/item/%E7%BD%91%E7%BB%9C%E5%8F%B7/2634355?fr=aladdin

标签:函数,ip,是否是,合法,计算机网络,地址,IP地址,IPy,iptype
来源: https://blog.csdn.net/m0_53115123/article/details/114527278