python - 如何在不使用循环的情况下将 IPv4 地址从字节转换为字符串?
问题描述
我有一个简单的 python 脚本,它创建一个 socket AF_PACKET
,它解析所有 IPv4 数据包并检索源和目标 IP 地址:
import socket
import struct
def get_ip(s):
return '.'.join([str(ord(symbol)) for symbol in s])
def main():
conn = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(3))
while True:
pkt, addr = conn.recvfrom(65536)
proto = struct.unpack('! H', pkt[12:14])
eth_proto = socket.htons(proto[0])
print('eth_proto = ', eth_proto)
if eth_proto == 8:
src, target = struct.unpack('! 4s 4s', pkt[26:34])
source_ip = get_ip(src)
destination_ip = get_ip(target)
print('Source IP = ', source_ip)
print('Destination IP = ', destination_ip)
main()
是否可以重构获取 IP 地址,使其看起来更好并且不使用此循环:
'.'.join([str(ord(symbol)) for symbol in s])
解决方案
如果您使用的是 Python 2(因为您已链接到 Python 2 文档),则可以使用 bytearray 和格式字符串来删除显式循环。
>>> s = '\n\x0b\xfa\x01'
>>> '{}.{}.{}.{}'.format(*bytearray(s))
'10.11.250.1'
如果您使用的是 Python 3.3+,则可以使用标准库的ipaddress模块。
>> ipa2 = ipaddress.ip_address(b'\n\x0b\xfa\x01')
>>> ipa2
IPv4Address('10.11.250.1')
>>> str(ipa2)
'10.11.250.1'
推荐阅读
- python - 日期是否在范围内?如何比较日期时间 Python?
- web - 如何修复“?Itemid =在网站地址joomla”
- authentication - 如何使用asp.net web api在swagger ui的url标头中传递访问令牌?
- android - 编译 Xerces-C Android
- ruby-on-rails - Created_at nil 即使在成功创建后
- c# - 通过 WinRM 从 PowerShell 脚本按值返回对象,而不是按引用
- android - checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) 返回 true,即使我的 GPS 已关闭
- python - 每个时间步长有多个值的熊猫滚动
- css - 在 Ionic 中均匀分布元素的最佳实践是什么?
- utf-8 - 为什么iconv不能转换字符