小记
记得在工作中,遇到过如何判断IP是否合法
这种问题,之前也是通过各种百度来解决,也没搞明白到底是怎么搞的。现在看Flask源码里写了一个函数,注释就叫:确定给定的字符串是否为 IP 地址(Determine if the given string is an IP address.),写的也是相当简单,借此记录下来。
Flask源码
版本: 1.1.x
路径: /flask/helper.py
行:[1128]
import socket
def is_ip(value):
"""Determine if the given string is an IP address.
Python 2 on Windows doesn't provide ``inet_pton``, so this only
checks IPv4 addresses in that environment.
翻译:windows上的Python2没有 `inet_pton`,所以在环境中只能检查ipv4地址
:param value: value to check
:type value: str
:return: True if string is an IP address
:rtype: bool
"""
if PY2 and os.name == "nt":
try:
socket.inet_aton(value)
return True
except socket.error:
return False
for family in (socket.AF_INET, socket.AF_INET6):
try:
socket.inet_pton(family, value)
except socket.error:
pass
else:
return True
return False
源码中,主要的两个函数就是:inet_aton
,inet_pton
。
在官方文档socket模块中,是这样解释的:
函数名 | 解释 | 报错 |
---|---|---|
socket.inet_aton(ip_string) | 将 IPv4 地址从点分十进制字符串格式(如 ‘123.45.67.89’ )转换为 32 位压缩二进制格式,转换后为字节对象,长度为四个字符。注意,具体什么样的地址有效取决于 inet_aton() 的底层 C 实现。 不支持IPv6!! | OSError: 函数调用出错 |
socket.inet_ntoa(packed_ip) | 将 32 位压缩 IPv4 地址(一个类字节对象,长 4 个字节)转换为标准的点分十进制字符串形式(如 ‘123.45.67.89’ )。 同样不支持IPv6!! | OSError: 函数调用出错 |
socket.inet_pton(address_family, ip_string) | 将特定地址簇的 IP 地址(字符串)转换为压缩二进制格式。 支持IPv4和IPv6 | ValueError:地址对象与家族簇长度不符 OSError: 函数调用出错 |
socket.inet_ntop(address_family, packed_ip) | 将特定地址簇的 IP 地址(字符串)转换为压缩二进制格式。 将压缩 IP 地址(一个 类字节对象,数个字节长)转换为标准的、特定地址簇的字符串形式(如 ‘7.10.0.5’ 或 ‘5aef:2b::8’ ) 支持IPv4和IPv6 | ValueError:地址对象与家族簇长度不符 OSError: 函数调用出错 |
总结
利用python的socket内建方法可以实现测试IP地址是否合法。