python IP地址轉(zhuǎn)整數(shù)
背景
今天有人問我 “為什么數(shù)據(jù)庫中有人推薦使用 int 類型來保存 IP 地址?”。現(xiàn)在(2020年)來看這個東西已經(jīng)有點過時了,一方面是磁盤空間不在那么貴,另一方面是 IPv6 與這條法則不兼容。
下面我們就來看一下把 IPv4 地址轉(zhuǎn)換成整數(shù)的原理和收益各是什么。
轉(zhuǎn)換的原理
一個 IPv4 類的地址共分為四個部分 0.0.0.0 然而每一個部分的取值范圍都在 0 ~ 255;也就是說每一個部分都可以用一個字節(jié)來保存,總共寫個字節(jié)就夠了,4 個字節(jié)不就是 int 嗎?
第一步 把 IP 地址的各個部分轉(zhuǎn)換為一個字節(jié),并拼接它們,那么會得到一個 4 字節(jié)的串。
import structdef aton(ip_address: str) -> bytes: result = [] for i in ip_address.split(’.’): result.append(struct.pack('!B', int(i))) return b’’.join(result)
第二步 把字節(jié)串轉(zhuǎn)換成整數(shù)。
In [2]: aton('127.0.0.1') Out[2]: b’x7fx00x00x01’In [3]: int.from_bytes(b’x7fx00x00x01’,’big’) Out[3]: 2130706433
這樣我們就把 IPv4 地址轉(zhuǎn)換成了一個整數(shù),完整的代碼如下。
import structdef 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
轉(zhuǎn)換的收益與限制
如果不做轉(zhuǎn)換可以使用 varchar 來保存 IPv4 地址,這樣的話需要 15 (3*4 + 3) 個字節(jié)才行;如果轉(zhuǎn)換一下只需要 4 個字節(jié)就行了,節(jié)約了磁盤空間,可能會多用點 cpu 時間。
今天來說 IPv6 已經(jīng)是主流,它的長度直接從之前的 4 字節(jié)直接漲到了 16 字節(jié);int 不再能滿足需求,為了可以統(tǒng)一處理這兩種類型的 IP 現(xiàn)在推薦使用 varchar 來保存。
inet_aton 與 inet_ntoa
這一對 IP 是 IPv4 時代的轉(zhuǎn)換函數(shù),目前來看已經(jīng)過時。
1、inet_aton IP 轉(zhuǎn)數(shù)字。
In [4]: socket.inet_aton('127.0.0.1') Out[4]: b’x7fx00x00x01’
2、inet_ntoa 數(shù)字轉(zhuǎn) IP。
In [5]: socket.inet_ntoa(b’x7fx00x00x01’) 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’Zxefx00+x00x00x00x00x00x00x00x00x00x00x00x08’In [7]: socket.inet_ntop(socket.AF_INET6,b’Zxefx00+x00x00x00x00x00x00x00x00x00x00x00x08’) Out[7]: ’5aef:2b::8’In [8]: socket.inet_pton(socket.AF_INET,'127.0.0.1') Out[8]: b’x7fx00x00x01’In [9]: socket.inet_ntop(socket.AF_INET,b’x7fx00x00x01’) Out[9]: ’127.0.0.1’
以上就是python IP 地址轉(zhuǎn)整數(shù)的詳細內(nèi)容,更多關(guān)于python ip地址轉(zhuǎn)整數(shù)的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
