Как я могу преобразовать IPv4-адрес из байтов в строку без использования цикла? - PullRequest
0 голосов
/ 09 января 2019

У меня есть простой скрипт на python, который создает сокет 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])

Формат символов описан здесь: https://docs.python.org/2/library/struct.html

1 Ответ

0 голосов
/ 10 января 2019

Если вы используете 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'
...