Quelle est la meilleure façon de transformer une chaîne sous cette forme en adresse IP: "0200A8C0"
. Les "octets" présents dans la chaîne sont dans l'ordre inverse, c'est-à-dire que la chaîne d'exemple donnée devrait générer 192.168.0.2
.Convertir la chaîne hexadécimale "little endian" en adresse IP en Python
Répondre
manipulation d'adresses réseau est fourni par le module de prise.
convertir une adresse IPv4 emballé 32 bits (une chaîne de quatre caractères de longueur) à sa représentation standard de chaîne en pointillé quad-(par exemple, « 123.45.67.89 »). Ceci est utile lorsque vous conversez avec un programme qui utilise la bibliothèque C standard et nécessite des objets de type struct in_addr, qui est le type C pour les données binaires compressées 32 bits que cette fonction prend en argument.
Vous pouvez traduire votre chaîne hexadécimale à l'aide packed ip
struct.pack()
et le petit endian, le format long non signé.
>>> import socket
>>> import struct
>>> addr_long = int("0200A8C0",16)
>>> hex(addr_long)
'0x200a8c0'
>>> struct.pack("<L", addr_long)
'\xc0\xa8\x00\x02'
>>> socket.inet_ntoa(struct.pack("<L", addr_long))
'192.168.0.2'
>>>
Vous pouvez faire quelque chose comme ceci:
>>> s = '0200A8C0'
>>> octets = [s[i:i+2] for i in range(0, len(s), 2)]
>>> ip = [int(i, 16) for i in reversed(octets)]
>>> ip_formatted = '.'.join(str(i) for i in ip)
>>> print ip_formatted
192.168.0.2
La division d'octets pourrait probablement se faire plus élégante, mais je ne peux pas penser à une façon plus simple du haut de ma tête.
EDIT: Ou sur une ligne:
>>> s = '0200A8C0'
>>> print '.'.join(str(int(i, 16)) for i in reversed([s[i:i+2] for i in range(0, len(s), 2)]))
192.168.0.2
ouais Teh groupe en particulier arrive à moi. Je ne peux pas trouver un moyen sympa de "tronquer" les octets, et itérer _those_ dans l'ordre inverse, j'espère que quelqu'un connaît un moyen –
@Max, la réponse de Roger contient une façon très intrigante de le faire. –
>>> s = "0200A8C0"
>>> bytes = ["".join(x) for x in zip(*[iter(s)]*2)]
>>> bytes
['02', '00', 'A8', 'C0']
>>> bytes = [int(x, 16) for x in bytes]
>>> bytes
[2, 0, 168, 192]
>>> print ".".join(str(x) for x in reversed(bytes))
192.168.0.2
Il est court et clair; Enveloppez-vous dans une fonction avec vérification d'erreur pour répondre à vos besoins.
fonctions de regroupement Handy:
def group(iterable, n=2, missing=None, longest=True):
"""Group from a single iterable into groups of n.
Derived from http://bugs.python.org/issue1643
"""
if n < 1:
raise ValueError("invalid n")
args = (iter(iterable),) * n
if longest:
return itertools.izip_longest(*args, fillvalue=missing)
else:
return itertools.izip(*args)
def group_some(iterable, n=2):
"""Group from a single iterable into groups of at most n."""
if n < 1:
raise ValueError("invalid n")
iterable = iter(iterable)
while True:
L = list(itertools.islice(iterable, n))
if L:
yield L
else:
break
@Roger, comment fonctionne ce 'zip (* [iter (s)] * 2)' fonctionne? Cela m'intéresse beaucoup. –
Ceci est tout à fait le hack! 'iter (s)' renvoie un itérateur sur la chaîne. Multiplier la liste de cet itérateur par 2 va créer deux références ** au même itérateur **. 'zip()' renvoie une liste de tuples contenant un élément de chacun de ses arguments. Puisque les deux arguments sont le même itérateur, il en prendra deux fois pour chaque tuple, renvoyant un tuple de chaque 2 caractères adjacents. Je n'aurais jamais pensé essayer quelque chose comme ça. : D –
@Matt: C'est le noyau de la plupart des recettes de "groupage" que j'ai vues, et Max l'a bien expliqué. Mettra à jour pour inclure deux fonctions courtes dans cette veine. –
Mon essai:
a = '0200A8C0'
indices = range(0, 8, 2)
data = [str(int(a[x:x+2], 16)) for x in indices]
'.'.join(reversed(data))
La réponse la plus utile, IMO. –
Vous voulez " Omnifarious
@Omnifarious, comment exactement cela "effet long/int" il ici? –