簡體   English   中英

將 IP 字符串轉換為數字,反之亦然

[英]Convert an IP string to a number and vice versa

如何使用 python 將作為str的 IP 地址轉換為十進制數,反之亦然?

例如,對於 IP 186.99.109.000 <type'str'> ,我想要一個易於存儲在數據庫中的十進制或二進制形式,然后檢索它。

將 IP 字符串轉換為長整數:

import socket, struct

def ip2long(ip):
    """
    Convert an IP string to long
    """
    packedIP = socket.inet_aton(ip)
    return struct.unpack("!L", packedIP)[0]

另一種方式:

>>> socket.inet_ntoa(struct.pack('!L', 2130706433))
'127.0.0.1'

以下是截至 2017-06 年所有選項的摘要。 所有模塊要么是標准庫的一部分,要么可以通過pip install

ip地址模塊

模塊 ipaddress ( doc ) 是自 v3.3 以來標准庫的一部分,但它也可用作 python v2.6、v2.7 的外部模塊。

>>> import ipaddress
>>> int(ipaddress.ip_address('1.2.3.4'))
16909060
>>> ipaddress.ip_address(16909060).__str__()
'1.2.3.4'
>>> int(ipaddress.ip_address(u'1000:2000:3000:4000:5000:6000:7000:8000'))
21268296984521553528558659310639415296L
>>> ipaddress.ip_address(21268296984521553528558659310639415296L).__str__()
u'1000:2000:3000:4000:5000:6000:7000:8000'

無模塊導入(僅限 IPv4)

無需導入,但僅適用於 IPv4,並且代碼比任何其他選項都長。

>>> ipstr = '1.2.3.4'
>>> parts = ipstr.split('.')
>>> (int(parts[0]) << 24) + (int(parts[1]) << 16) + \
          (int(parts[2]) << 8) + int(parts[3])
16909060
>>> ipint = 16909060
>>> '.'.join([str(ipint >> (i << 3) & 0xFF)
          for i in range(4)[::-1]])
'1.2.3.4'

模塊網絡地址

netaddr 是一個外部模塊,但自 Python 2.5 ( doc ) 以來非常穩定且可用

>>> import netaddr
>>> int(netaddr.IPAddress('1.2.3.4'))
16909060
>>> str(netaddr.IPAddress(16909060))
'1.2.3.4'
>>> int(netaddr.IPAddress(u'1000:2000:3000:4000:5000:6000:7000:8000'))
21268296984521553528558659310639415296L
>>> str(netaddr.IPAddress(21268296984521553528558659310639415296L))
'1000:2000:3000:4000:5000:6000:7000:8000'

模塊套接字和結構(僅限 ipv4)

這兩個模塊都是標准庫的一部分,代碼很短,有點神秘,只有 IPv4。

>>> import socket, struct
>>> ipstr = '1.2.3.4'
>>> struct.unpack("!L", socket.inet_aton(ipstr))[0]
16909060
>>> ipint=16909060
>>> socket.inet_ntoa(struct.pack('!L', ipint))
'1.2.3.4'

在模塊netaddr使用IPAddress類。

ipv4 str -> int :

print int(netaddr.IPAddress('192.168.4.54'))
# OUTPUT: 3232236598

ipv4 int -> str

print str(netaddr.IPAddress(3232236598))
# OUTPUT: 192.168.4.54

ipv6 str -> int :

print int(netaddr.IPAddress('2001:0db8:0000:0000:0000:ff00:0042:8329'))
# OUTPUT: 42540766411282592856904265327123268393

ipv6 int -> str

print str(netaddr.IPAddress(42540766411282592856904265327123268393))
# OUTPUT: 2001:db8::ff00:42:8329

從 Python 3.3 開始,就有 ipaddress 模塊可以完成這項工作: https : //docs.python.org/3/library/ipaddress.html PyPI 上也提供了 Python 2.x 的向后移植。

用法示例:

import ipaddress

ip_in_int = int(ipaddress.ip_address('192.168.1.1'))
ip_in_hex = hex(ipaddress.ip_address('192.168.1.1'))

這是一行答案:

import socket, struct

def ip2long_1(ip):
    return struct.unpack("!L", socket.inet_aton(ip))[0]

def ip2long_2(ip):
    return long("".join(["{0:08b}".format(int(num)) for num in ip.split('.')]), 2)

def ip2long_3(ip):
    return long("".join(["{0:08b}".format(num) for num in map(int, ip.split('.'))]), 2)

執行時間:

ip2long_1 => 0.0527065660363234(最佳)
ip2long_2 => 0.577211893924598
ip2long_3 => 0.5552745958088666

將 IP 轉換為整數:

python -c "print sum( [int(i)*2**(8*j) for  i,j in zip( '10.20.30.40'.split('.'), [3,2,1,0]) ] )"

將整數轉換為 IP :

python -c "print '.'.join( [ str((169090600 >> 8*i) % 256)  for i in [3,2,1,0] ])" 

沒有任何模塊導入的一行解決方案:

ip2int = lambda ip: reduce(lambda a, b: (a << 8) + b, map(int, ip.split('.')), 0)
int2ip = lambda n: '.'.join([str(n >> (i << 3) & 0xFF) for i in range(0, 4)[::-1]])

例子:

In [3]: ip2int('121.248.220.85')
Out[3]: 2046352469

In [4]: int2ip(2046352469)
Out[4]: '121.248.220.85'
def ip2Hex(ip = None):
    '''Returns IP in Int format from Octet form'''
    #verifyFormat(ip)
    digits=ip.split('.')
    numericIp=0
    count=0
    for num in reversed(digits):
        print "%d " % int(num)
        numericIp += int(num) * 256 **(count)
        count +=1
    print "Numeric IP:",numericIp
    print "Numeric IP Hex:",hex(numericIp)

ip2Hex('192.168.192.14')
ip2Hex('1.1.1.1')
ip2Hex('1.0.0.0')

這是一個

def ipv4_to_int(ip):
    octets = ip.split('.')
    count = 0
    for i, octet in enumerate(octets):
        count += int(octet) << 8*(len(octets)-(i+1))
    return count

如果您的 IP 地址在clean_ip ,您可以使用庫DataPrep中的函數 clean_ip。 使用pip install dataprep

from dataprep.clean import clean_ip
df = pd.DataFrame({"ip": ["186.99.109.000", "127.0.0.1", "1.2.3.4"]})

要轉換為十進制格式,請將參數output_format設置為"integer"

df2 = clean_ip(df, "ip", output_format="integer")
# print(df2)
               ip    ip_clean
0  186.99.109.000  3127078144
1       127.0.0.1  2130706433
2         1.2.3.4    16909060

要轉換為二進制格式,請將參數output_format設置為"binary"

df2 = clean_ip(df, "ip", output_format="binary")
# print(df2)
               ip                          ip_clean
0  186.99.109.000  10111010011000110110110100000000
1       127.0.0.1  01111111000000000000000000000001
2         1.2.3.4  00000001000000100000001100000100

要轉換回 IPv4,請將參數output_format設置為"compressed"

df = pd.DataFrame({"ip": [3127078144, 2130706433, 16909060]})
df2 = clean_ip(df, "ip", output_format="compressed")
# print(df2)
           ip      ip_clean
0  3127078144  186.99.109.0
1  2130706433     127.0.0.1
2    16909060       1.2.3.4

您必須先將包含 IP 地址的字符串轉換為一個字節或一個字節串,然后才能開始通信。 根據下面的代碼,您的錯誤將得到解決。 確保您的代碼總體上正常工作。

string = '192.168.1.102'
new_string = bytearray(string,"ascii")
ip_receiver = new_string
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(text.encode(), (ip_receiver, 5252))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM