1. 程式人生 > 程式設計 >python IP地址轉整數

python IP地址轉整數

背景

今天有人問我 “為什麼資料庫中有人推薦使用 int 型別來儲存 IP 地址?”。現在(2020年)來看這個東西已經有點過時了,一方面是磁碟空間不在那麼貴,另一方面是 IPv6 與這條法則不相容。

下面我們就來看一下把 IPv4 地址轉換成整數的原理和收益各是什麼。

轉換的原理

一個 IPv4 類的地址共分為四個部分 0.0.0.0 然而每一個部分的取值範圍都在 0 ~ 255;也就是說每一個部分都可以用一個位元組來儲存,總共寫個位元組就夠了,4 個位元組不就是 int 嗎?

第一步 把 IP 地址的各個部分轉換為一個位元組,並拼接它們,那麼會得到一個 4 位元組的串。

import struct

def aton(ip_address: str) -> bytes:
  result = []
  for i in ip_address.split('.'):
    result.append(struct.pack("!B",int(i)))
  return b''.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 地址轉換成了一個整數,完整的程式碼如下。

import struct


def aton(ip_address: str) -> bytes:
  result = []
  for i in ip_address.split('.'):
    result.append(struct.pack("!B",int(i)))
  return b''.join(result)


if __name__ == "__main__":
  bts = aton("127.0.0.1")
  print(int.from_bytes(bts,'big'))

執行效果如下。

python3 main.py 
2130706433

轉換的收益與限制

如果不做轉換可以使用 varchar 來儲存 IPv4 地址,這樣的話需要 15 (3*4 + 3) 個位元組才行;如果轉換一下只需要 4 個位元組就行了,節約了磁碟空間,可能會多用點 cpu 時間。

今天來說 IPv6 已經是主流,它的長度直接從之前的 4 位元組直接漲到了 16 位元組;int 不再能滿足需求,為了可以統一處理這兩種型別的 IP 現在推薦使用 varchar 來儲存。

inet_aton 與 inet_ntoa

這一對 IP 是 IPv4 時代的轉換函式,目前來看已經過時。

1、inet_aton IP 轉數字。

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'

以上就是python IP 地址轉整數的詳細內容,更多關於python ip地址轉整數的資料請關注我們其它相關文章!