web-dev-qa-db-ja.com

IP文字列から整数への変換、およびPython

「xxx.xxx.xxx.xxx」形式のipを整数表現に変換し、この形式から戻る必要があるスクリプトで少し問題があります。

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`

誰もそれを修正する方法を知っていますか?

41
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
81
fiorix

Python 3には、非常に単純な変換を特徴とする ipaddress モジュールがあります。

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

純粋なpython追加モジュールを使用しない場合

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

結果:

192.168.0.1 -> 3232235521
3232235521 -> 192.168.0.1
19
Bruno Adelé

文字列のデコードを中断する左ゼロパディングを失います。

作業関数は次のとおりです。

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

以下は、IPv4およびIPv6用の最速かつ最も単純な(私の知る限り)コンバーターです。

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

inet_ntop()およびstructモジュールを使用しないPythonコードは、何をしていても、これよりも桁違いに遅くなります。

6
adobriyan

一行

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

私のアプローチは、表示されるのではなく、保存されている方法で数字を直接見て、表示形式から保存された形式に、またはその逆に操作することです。

したがって、IPアドレスからintへ

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

これは各フィールドを評価し、正しいオフセットにシフトし、それらをすべて合計して、IPアドレスの表示を数値にきれいに変換します。

逆方向の場合、intからIPアドレスへ

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

数値表現は最初に16進数の文字列表現に変換されます。これはシーケンスとして操作でき、分割が容易になります。次に、IP文字列の反復子への2つの参照のリストを圧縮することにより提供されるペアのタプルに '' .joinをマッピングすることにより、ペアが抽出されます( How does Zip(* [iter(s)] * n)を参照) work? )、これらのペアは16進文字列表現からint文字列表現に変換され、「。」で結合されます。

0
Gavi Teitz

私は次を使用しました:

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

よりわかりやすい方法を教えてください:

ipから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

上記:

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

に相当 :

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

また:

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

に相当 :

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

または:

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