【发布时间】:2023-03-20 21:25:01
【问题描述】:
将这种形式的字符串转换为 IP 地址的最佳方法是:"0200A8C0"。字符串中的“八位字节”顺序相反,即给定的示例字符串应该生成192.168.0.2。
【问题讨论】:
标签: python sockets ip-address endianness
将这种形式的字符串转换为 IP 地址的最佳方法是:"0200A8C0"。字符串中的“八位字节”顺序相反,即给定的示例字符串应该生成192.168.0.2。
【问题讨论】:
标签: python sockets ip-address endianness
网络地址操作由套接字模块提供。
将 32 位压缩 IPv4 地址(长度为四个字符的字符串)转换为其标准点分四进制字符串表示形式(例如,“123.45.67.89”)。这在与使用标准 C 库并需要 struct in_addr 类型的对象的程序进行对话时很有用,这是该函数作为参数的 32 位打包二进制数据的 C 类型。
您可以使用struct.pack() 将您的十六进制字符串转换为packed ip
和小端、无符号长格式。
s = "0200A8C0"
import socket
import struct
addr_long = int(s, 16)
print(hex(addr_long)) # '0x200a8c0'
print(struct.pack("<L", addr_long)) # '\xc0\xa8\x00\x02'
print(socket.inet_ntoa(struct.pack("<L", addr_long))) # '192.168.0.2'
【讨论】:
192.168.10.5 十六进制为 c0a80a05。当我使用这个 sn-p 从 HEX 转换为 IP 时,我得到5.10.168.192。这是正确的,但相反。为了使它工作,我必须将<L 更改为>L,如果我从用户那里获取输入并且我不知道输入是什么十六进制,这没有任何意义!你知道如何让它适用于任何 HEX 值吗?谢谢
>>> 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
简洁明了;将其封装在一个带有错误检查功能的函数中以满足您的需求。
方便的分组功能:
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
【讨论】:
zip(*[iter(s)]*2) 是如何工作的?我对此很感兴趣。
iter(s) 在字符串上返回一个迭代器。将此迭代器的列表乘以 2 将创建两个对同一迭代器的引用。 zip() 返回一个元组列表,其中包含每个参数中的一个元素。由于两个参数都是相同的迭代器,因此每个元组将从它获取两次,返回每 2 个相邻字符的元组。我从来没有想过尝试这样的事情。 :D
你可以这样做:
>>> 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
八位字节拆分可能会更优雅,但我想不出更简单的方法。
编辑:或一行:
>>> 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
【讨论】:
我的尝试:
a = '0200A8C0'
indices = range(0, 8, 2)
data = [str(int(a[x:x+2], 16)) for x in indices]
'.'.join(reversed(data))
【讨论】: