it-swarm.com.de

Umwandlung von IP-String in Ganzzahl und rückwärts in Python

ich habe ein kleines Problem mit meinem Skript, bei dem ich IP in der Form 'xxx.xxx.xxx.xxx' in eine Ganzzahldarstellung konvertieren und von dieser Form zurückgehen muss.

def iptoint(ip):
    return int(socket.inet_aton(ip).encode('hex'),16)

def inttoip(ip):
    return socket.inet_ntoa(hex(ip)[2:].decode('hex'))


In [65]: inttoip(iptoint('192.168.1.1'))
Out[65]: '192.168.1.1'

In [66]: inttoip(iptoint('4.1.75.131'))
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)

/home/thc/<ipython console> in <module>()

/home/thc/<ipython console> in inttoip(ip)

error: packed IP wrong length for inet_ntoa`

Weiß jemand, wie man das repariert?

38
thc_flow
#!/usr/bin/env python
import socket
import struct


def ip2int(addr):
    return struct.unpack("!I", socket.inet_aton(addr))[0]


def int2ip(addr):
    return socket.inet_ntoa(struct.pack("!I", addr))


print(int2ip(0xc0a80164)) # 192.168.1.100
print(ip2int('10.0.0.1')) # 167772161
74
fiorix

Python 3 verfügt über das Modul ipaddress , das eine sehr einfache Konvertierung bietet:

int(ipaddress.IPv4Address("192.168.0.1"))
str(ipaddress.IPv4Address(3232235521))
27
markhor

In reinem Python ohne Zusatzmodul

def IP2Int(ip):
    o = map(int, ip.split('.'))
    res = (16777216 * o[0]) + (65536 * o[1]) + (256 * o[2]) + o[3]
    return res


def Int2IP(ipnum):
    o1 = int(ipnum / 16777216) % 256
    o2 = int(ipnum / 65536) % 256
    o3 = int(ipnum / 256) % 256
    o4 = int(ipnum) % 256
    return '%(o1)s.%(o2)s.%(o3)s.%(o4)s' % locals()

# Example
print('192.168.0.1 -> %s' % IP2Int('192.168.0.1'))
print('3232235521 -> %s' % Int2IP(3232235521))

Ergebnis:

192.168.0.1 -> 3232235521
3232235521 -> 192.168.0.1
17
Bruno Adelé

Sie verlieren das Left-Zero-Padding, wodurch die Dekodierung Ihrer Zeichenfolge unterbrochen wird.

Hier ist eine Arbeitsfunktion:

def inttoip(ip):
    return socket.inet_ntoa(hex(ip)[2:].zfill(8).decode('hex'))
12
ThiefMaster

Nachfolgend sind die schnellsten und unkompliziertesten (nach meinem besten Wissen) Konverter für IPv4 und IPv6 aufgeführt:

    try:
        _str = socket.inet_pton(socket.AF_INET, val)
    except socket.error:
        raise ValueError
    return struct.unpack('!I', _str)[0]
    -------------------------------------------------
    return socket.inet_ntop(socket.AF_INET, struct.pack('!I', n))
    -------------------------------------------------
    try:
        _str = socket.inet_pton(socket.AF_INET6, val)
    except socket.error:
        raise ValueError
    a, b = struct.unpack('!2Q', _str)
    return (a << 64) | b
    -------------------------------------------------
    a = n >> 64
    b = n & ((1 << 64) - 1)
    return socket.inet_ntop(socket.AF_INET6, struct.pack('!2Q', a, b))

Python-Code, der das inet_ntop()- und struct-Modul nicht verwendet, ist um eine Größenordnung langsamer als diese, unabhängig davon, was er tut.

6
adobriyan

Eine Linie

reduce(lambda out, x: (out << 8) + int(x), '127.0.0.1'.split('.'), 0)
3
Thomas Webber

Mein Ansatz ist es, die Zahl, in der sie gespeichert ist, direkt anzuzeigen, anstatt sie anzuzeigen, und sie vom Anzeigeformat in das gespeicherte Format und umgekehrt zu manipulieren.

Also von einer IP-Adresse zu einem int:

def convertIpToInt(ip):
    return sum([int(ipField) << 8*index for index, ipField in enumerate(reversed(ip.split('.')))])

Dadurch wird jedes Feld ausgewertet und auf den korrekten Offset verschoben. Dann werden alle Felder zusammengefasst und die Anzeige der IP-Adresse wird in den numerischen Wert umgewandelt.

In umgekehrter Richtung von einem int zu einer IP-Adresse:

def convertIntToIp(ipInt):
    return '.'.join([str(int(ipHexField, 16)) for ipHexField in (map(''.join, Zip(*[iter(str(hex(ipInt))[2:].zfill(8))]*2)))])

Die numerische Darstellung wird zuerst in ihre hexadezimale Zeichenfolgendarstellung konvertiert, die als Sequenz geändert werden kann, um das Auflösen zu erleichtern. Dann werden Paare extrahiert, indem '' .join 'auf Tupel von Paaren abgebildet wird, die bereitgestellt werden, indem eine Liste von zwei Referenzen zu einem Iterator des IP-Strings gezippt wird (siehe Wie funktioniert Zip (* [iter (s)] * n)? ), und diese Paare werden wiederum von Hex-String-Darstellungen in Int-String-Darstellungen konvertiert und durch '.' verbunden.

0
Gavi Teitz

Ich habe folgendes verwendet:

ip2int = lambda ip: reduce(lambda a,b: long(a)*256 + long(b), ip.split('.'))

ip2int('192.168.1.1')

#output

3232235777L

# from int to ip
int2ip = lambda num: '.'.join( [ str((num >> 8*i) % 256)  for i in [3,2,1,0] ])

int2ip(3232235777L)

#output

'192.168.1.1'
0
J0KER11

Lassen Sie mich einen verständlicheren Weg geben:

ip zu int  

def str_ip2_int(s_ip='192.168.1.100'):
    lst = [int(item) for item in s_ip.split('.')]
    print lst   
    # [192, 168, 1, 100]

    int_ip = lst[3] | lst[2] << 8 | lst[1] << 16 | lst[0] << 24
    return int_ip   # 3232235876

Obenstehendes:

lst = [int(item) for item in s_ip.split('.')]

gleichwertig :

lst = map(int, s_ip.split('.'))

ebenfalls:

int_ip = lst[3] | lst[2] << 8 | lst[1] << 16 | lst[0] << 24

gleichwertig :

int_ip = lst[3] + (lst[2] << 8) + (lst[1] << 16) + (lst[0] << 24)

int_ip = lst[3] + lst[2] * pow(2, 8) + lst[1] * pow(2, 16) + lst[0] * pow(2, 24)

int zu ip:

def int_ip2str(int_ip=3232235876):
    a0 = str(int_ip & 0xff)
    a1 = str((int_ip & 0xff00) >> 8) 
    a2 = str((int_ip & 0xff0000) >> 16)
    a3 = str((int_ip & 0xff000000) >> 24)

    return ".".join([a3, a2, a1, a0])

oder:

def int_ip2str(int_ip=3232235876):
    lst = []
    for i in xrange(4):
        shift_n = 8 * i
        lst.insert(0, str((int_ip >> shift_n) & 0xff))

    return ".".join(lst)
0
Jayhello