web-dev-qa-db-fra.com

Convertir une chaîne IP en un nombre et vice versa

Comment utiliser python pour convertir une adresse IP sous la forme d'une str en un nombre décimal et vice versa? 

Par exemple, pour l'IP 186.99.109.000 <type'str'>, j'aimerais une forme décimale ou binaire facile à stocker dans une base de données, puis à récupérer.

34
user987055

convertir une chaîne IP en entier long:

import socket, struct

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

l'inverse:

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

Voici un résumé de toutes les options à compter de 2017-06. Tous les modules font partie de la bibliothèque standard ou peuvent être installés via pip install.

module ipaddress

Le module ipaddress ( doc ) fait partie de la bibliothèque standard depuis la v3.3 mais il est également disponible en tant que module externe pour 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'

Aucune importation de module (IPv4 uniquement)

Rien à importer, mais ne fonctionne que pour IPv4 et le code est plus long que toute autre option.

>>> 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'

Module netaddr

netaddr est un module externe mais très stable et disponible depuis 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'

Modules socket et struct (ipv4 uniquement)

Les deux modules font partie de la bibliothèque standard, le code est court, un bit cryptique et IPv4 uniquement.

>>> 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'
31
ndemou

Utilisez la classe IPAddress dans le module netaddr.

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
25
fred.yu

Depuis Python 3.3, il existe un module ipaddress qui fait exactement ce travail entre autres: https://docs.python.org/3/library/ipaddress.html . Les backports pour Python 2.x sont également disponibles sur PyPI.

Exemple d'utilisation:

import ipaddress

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

Voici une réponse en ligne:

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)

Temps d'exécution:

ip2long_1 => 0.0527065660363234 (Le meilleur) 
ip2long_2 => 0.577211893924598 
ip2long_3 => 0.5552745958088666

5
Tomer Zait

Solution à une ligne sans aucune importation de module:

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]])

Exemple:

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

In [4]: int2ip(2046352469)
Out[4]: '121.248.220.85'
4
CodeColorist

Convertir l'IP en entier:

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

Convertir un entier en IP:

python -c "print '.'.join( [ str((169090600 >> 8*i) % 256)  for i in [3,2,1,0] ])" 
2
Indu Sharma
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')

En voici un

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
0
Said Ali Samed