将IP字符串转换为数字,反之亦然

use*_*055 41 python django

我如何使用python将一个IP地址转换为str十进制数,反之亦然?

例如,对于IP 186.99.109.000 <type'str'>,我希望有一个十进制或二进制形式,易于存储在数据库中,然后检索它.

Not*_*fer 88

将IP字符串转换为长整数:

import socket, struct

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

另一种方式:

>>> socket.inet_ntoa(struct.pack('!L', 2130706433))
'127.0.0.1'
Run Code Online (Sandbox Code Playgroud)

  • 喜欢python文档中的这一行`'form'!' 声称他们不记得网络字节顺序是big-endian还是little-endian的那些可怜的灵魂可以使用 (27认同)
  • 我明显使用bigindian的`>`而不是`!`. (3认同)

nde*_*mou 37

以下是截至2017-06的所有选项的摘要.所有模块都是标准库的一部分或可以通过安装pip install.

ipaddress模块

模块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'
Run Code Online (Sandbox Code Playgroud)

没有模块导入(仅限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'
Run Code Online (Sandbox Code Playgroud)

模块netaddr

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'
Run Code Online (Sandbox Code Playgroud)

模块socket和struct(仅限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'
Run Code Online (Sandbox Code Playgroud)


fre*_*.yu 25

IPAddress在模块中使用class netaddr.

ipv4 str- > int:

print int(netaddr.IPAddress('192.168.4.54'))
# OUTPUT: 3232236598
Run Code Online (Sandbox Code Playgroud)

ipv4 int- > str:

print str(netaddr.IPAddress(3232236598))
# OUTPUT: 192.168.4.54
Run Code Online (Sandbox Code Playgroud)

ipv6 str- > int:

print int(netaddr.IPAddress('2001:0db8:0000:0000:0000:ff00:0042:8329'))
# OUTPUT: 42540766411282592856904265327123268393
Run Code Online (Sandbox Code Playgroud)

ipv6 int- > str:

print str(netaddr.IPAddress(42540766411282592856904265327123268393))
# OUTPUT: 2001:db8::ff00:42:8329
Run Code Online (Sandbox Code Playgroud)


man*_*hiz 7

从Python 3.3开始,ipaddress模块​​就可以完成这项工作:https://docs.python.org/3/library/ipaddress.html.PyPI上也提供了Python 2.x的Backports.

用法示例:

import ipaddress

ip_in_int = int(ipaddress.ip_address('192.168.1.1'))
ip_in_hex = hex(ipaddress.ip_address('192.168.1.1'))
Run Code Online (Sandbox Code Playgroud)

  • 对于十六进制(ipaddress.ip_address('192.168.1.1')),出现错误。“IPv4Address”对象不能解释为整数。似乎使用十六进制(int(...))。了解新的 ipaddress 模块是件好事。 (2认同)

Tom*_*ait 5

这是一行答案:

import socket, struct

def ip2long_1(ip):
    return struct.unpack("!L", socket.inet_aton(ip))[0]
Run Code Online (Sandbox Code Playgroud)
def ip2long_2(ip):
    return long("".join(["{0:08b}".format(int(num)) for num in ip.split('.')]), 2)
Run Code Online (Sandbox Code Playgroud)
def ip2long_3(ip):
    return long("".join(["{0:08b}".format(num) for num in map(int, ip.split('.'))]), 2)
Run Code Online (Sandbox Code Playgroud)

执行时间:

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


小智 5

无需导入任何模块的一行解决方案:

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]])
Run Code Online (Sandbox Code Playgroud)

例子:

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

In [4]: int2ip(2046352469)
Out[4]: '121.248.220.85'
Run Code Online (Sandbox Code Playgroud)


小智 5

将 IP 转换为整数:

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

将整数转换为 IP :

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