Fork me on GitHub

判断字符串是否是内网地址(Python实现)

起因

最近一直在改需求没空刷题,且感冒带偏头痛真的很难受,好在昨晚服药后睡到半夜总算有点精神了,想了想,趁着头脑清新的时候刷道提拔。毕竟,”不积跬步,无以至千里”。

题目

这次刷的题据说是2019年bilibili的一道校招题,题目总体而言属于简单级别。不过不注意的人依然容易翻车,毕竟OJ系统判定和这人判定还是有一定区别的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
时间限制:1秒 空间限制:32768K

题目描述
从业 666 年的 BILIBILI 网络安全工程师 KindMo 最近很困惑,公司有一个业务总是受到 SSRF 攻击。请帮他写一个程序,判断输入的字符串是否属于内网IP,用于防御该漏洞。
我们知道常见的内网IP有,127.0.0.1,192.168.0.1 等。

输入描述:
每次输入仅包含一个IP字符串,即一个测试样例

输出描述:
对于每个测试实例输出整数1或0,
1代表True,即输入属于内网IP,
0代表False,即输入不属于内网IP或不是IP字符串。

示例1
输入
42.96.146.169

输出
0

think

分析

  • 如果没有深入思考,不少人会想直接把程序输入的IP放到list中遍历。这显然不可取,因为题目一开始就是有时间和空间限制,如果还不理解,请自己遍历所有的内网地址看看,故这个思路直接放弃。

  • 正确的思维方向自然是判断IP地址的4个网段的范围,然后进行判断,具体逻辑看代码。

必备知识点

1
2
3
4
5
6
7
8
私有IP地址范围:
A类:10.0.0.0-10.255.255.255
B类:172.16.0.0-172.31.255.255
C类:192.168.0.0-192.168.255.255

localhost:127.0.0.1

补充说明,上面所有IP数量综合为:17891329

题解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def check_internal_ip(check_ip):

check_ip_list = check_ip.split(".")
if len(check_ip_list) == 4:
a, b, c, d = check_ip_list

a = int(a)
b = int(b)
c = int(c)
d = int(d)

if a > 255 or b > 255 or c > 255 or d > 255:
return 0

elif a == 10 and b >= 0 and c >= 0 and d >= 0:
return 1

elif a == 172 and (16 <= b <= 31) and c >= 0 and d >= 0:
return 1

elif a == 192 and b == 168 and c >= 0 and d >= 0:
return 1

else:
return 0

else:
return 0

check_ip = input()
print(check_internal_ip(check_ip))

区别于他人简明的解答,这里对于输入我增加了对于>255, <0等异常输入的判断,对于不符合的输入,直接排除,加快程序运行效率,在我看来程序的性能和逻辑判断的严谨更为重要,当然最好能二者得兼。

原因

这道题其实挺简单的,那为什么要专门写个blog讲这个问题呢?请先看下这个题解:

1
2
if input()[:3] in ('127','192','10.','172'): print(1)
else: print(0)

在OJ系统上,这段代码能通过验证,但是,明眼人一下就能看出问题,IP地址验证逻辑不够严谨。

举例:当输入”192.168.333.0”或”10.399.399.299”时,结果如下:

1
2
3
4
In [7]: if input()[:3] in ('127','192','10.','172'): print(1)
...: else: print(0)
192.168.333.0
1

这段代码返回的检验结果是这个地址都是内网地址,然而实际上这都不是一个合法的IP地址(在每个合法的IP地址中,有4个3位数用“.”隔开的数字,而且每个三位数都在0到255之间)。

总结

这道题因为OJ系统的测试用例不足,导致很多不严谨的解法也能通过测试,单从通过OJ检测而言,即使取巧了也没什么,特别是对于习惯参加算法竞赛的人,自然是要分秒必争的。
但从实际开发的角度而言,只通过测试用例测试的场景就算完成的话是个坏习惯。在实在开发的过程中,我们应该更充分考虑各种场景,设计充足的测试用例来验证程序的功能和稳定性,在编码时也应有减轻业务压力的意识,定期审查自己的代码并持续优化改进之。

-------------  Fin    Thanks for reading!  -------------

本文标题:判断字符串是否是内网地址(Python实现)

文章作者:TesterCC

发布时间:2019年09月30日 - 11:09

最后更新:2019年09月30日 - 21:09

原始链接:http://blog.fullstackpentest.com/check-intranet-ip-with-python.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。