python IP地址转整数
背景
今天有人问我“为什么数据库中有人推荐使用int类型来保存IP地址?”。现在(2020年)来看这个东西已经有点过时了,一方面是磁盘空间不在那么贵,另一方面是IPv6与这条法则不兼容。
下面我们就来看一下把IPv4地址转换成整数的原理和收益各是什么。
转换的原理
一个IPv4类的地址共分为四个部分0.0.0.0然而每一个部分的取值范围都在0~255;也就是说每一个部分都可以用一个字节来保存,总共写个字节就够了,4个字节不就是int吗?
第一步把IP地址的各个部分转换为一个字节,并拼接它们,那么会得到一个4字节的串。
importstruct defaton(ip_address:str)->bytes: result=[] foriinip_address.split('.'): result.append(struct.pack("!B",int(i))) returnb''.join(result)
第二步把字节串转换成整数。
In[2]:aton("127.0.0.1") Out[2]:b'\x7f\x00\x00\x01' In[3]:int.from_bytes(b'\x7f\x00\x00\x01','big') Out[3]:2130706433
这样我们就把IPv4地址转换成了一个整数,完整的代码如下。
importstruct defaton(ip_address:str)->bytes: result=[] foriinip_address.split('.'): result.append(struct.pack("!B",int(i))) returnb''.join(result) if__name__=="__main__": bts=aton("127.0.0.1") print(int.from_bytes(bts,'big'))
运行效果如下。
python3main.py 2130706433
转换的收益与限制
如果不做转换可以使用varchar来保存IPv4地址,这样的话需要15(3*4+3)个字节才行;如果转换一下只需要4个字节就行了,节约了磁盘空间,可能会多用点cpu时间。
今天来说IPv6已经是主流,它的长度直接从之前的4字节直接涨到了16字节;int不再能满足需求,为了可以统一处理这两种类型的IP现在推荐使用varchar来保存。
inet_aton与inet_ntoa
这一对IP是IPv4时代的转换函数,目前来看已经过时。
1、inet_atonIP转数字。
In[4]:socket.inet_aton("127.0.0.1") Out[4]:b'\x7f\x00\x00\x01'
2、inet_ntoa数字转IP。
In[5]:socket.inet_ntoa(b'\x7f\x00\x00\x01') Out[5]:'127.0.0.1'
inet_pton与inet_ntop
这是一对新的API,这对API兼容了IPv4和IPv6。
In[6]:socket.inet_pton(socket.AF_INET6,"5aef:2b::8") Out[6]:b'Z\xef\x00+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08' In[7]:socket.inet_ntop(socket.AF_INET6,b'Z\xef\x00+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08') Out[7]:'5aef:2b::8' In[8]:socket.inet_pton(socket.AF_INET,"127.0.0.1") Out[8]:b'\x7f\x00\x00\x01' In[9]:socket.inet_ntop(socket.AF_INET,b'\x7f\x00\x00\x01') Out[9]:'127.0.0.1'
以上就是pythonIP地址转整数的详细内容,更多关于pythonip地址转整数的资料请关注毛票票其它相关文章!