LINUX.ORG.RU

python как «упаковать» в буфер разнородные данные?

 


1

1

Здравствуйте, коллеги!

Я даже не знаю как сформулировать свой вопрос правильно.

Покажу, что мне нужно на примере (С)

typedef struct {
int id;
char data[256];
}pack;

struct pack p;
p.id = 9999
memcpy(&p, "Hello", 5);

Для чего мне это нужно….

Для передачи пакета определенного формата по сети.

Первые 4 байта - ID пакета

Следом идут данные.

В питоновской программе данные будут представлять строки.

Я пока не представляю как «упаковать» подобную структуру.

Ответ на: комментарий от vvn_black

https://docs.python.org/3/library/struct.html

Спасибо большое!

Вроде, то что нужно, но не понимаю как этой фигней воспользоваться.

Допустим, мне нужно запаковать int 900 и строку «Hello»

Я делал так и ни фига не вышло

import struct
p = struct.pack(">is", 900, "Hello".encode())
f = open("text.bin", "wb")
f.fwrite(p)
f.close()

Что записалось в этот несчастный файл - не понятно. Точно, что ни чего похожего на «Hello» в нем нет.

Что я делаю не правильно?

HighMan
() автор топика
Ответ на: комментарий от HighMan
import struct

string = 'Hello'
num = 900

with open('test.bin', 'wb') as f:
    f.write(struct.pack(f'>i{len(string)}s', num, string.encode()))
$ hexdump -C test.bin 
00000000  00 00 03 84 48 65 6c 6c  6f                       |....Hello|
00000009
vvn_black ★★★★★
()
Последнее исправление: vvn_black (всего исправлений: 1)

Если не хочется заморачиваться с форматом сериализации данных и при этом с обоих сторон будет питон, можно использовать pickle.

Но как везде большими красными буквами написано, это огромная дыра в безопасности. Если у третьей стороны есть возможность хоть как-то изменить данные между сохранением и чтением, у третьей стороны по сути появляется возможность исполнения произвольного кода.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Если не хочется заморачиваться с форматом сериализации данных и > при этом с обоих сторон будет питон, можно использовать pickle.

Но как везде большими красными буквами написано, это огромная >дыра в безопасности. Если у третьей стороны есть возможность хоть >как-то изменить данные между сохранением и чтением, у третьей >стороны по сути появляется возможность исполнения произвольного >кода.

У меня на одной стороне Python, на другой сервер на C++ :)

HighMan
() автор топика
Последнее исправление: HighMan (всего исправлений: 1)
Ответ на: комментарий от vvn_black

Спасибо!

Разобрался сам и уже полез писать свое решение, как увидел ваш ответ. :)

Только для полной совместимости с кодом на C++ чуть изменил

struct.pack(f'>i{len(string)}s', num, string.encode())
# на
struct.pack(f'=i{len(string)}s', num, string.encode())
HighMan
() автор топика
Последнее исправление: HighMan (всего исправлений: 1)

ТС, ты хочешь переизобрести msgpack или протобуф? Алсо, будь проще

  • открыл BytesIO
  • сделал int.to_bytes
  • сделал сишную строку любым доступным методом
  • забрал/послал байты

Все это уложил в Protocol и все. Структ не нужен

upcFrost ★★★★★
()
Последнее исправление: upcFrost (всего исправлений: 2)