Как достать из кучи байт расширение и имя файла?

Из websocket приходит нечто такое:
WSMessage(type=<WSMsgType.BINARY: 2>, data=b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x05;\x00\x00\x01\x1b\x08\x06\x00\x00\x00\x15\xa9Ps\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\x00\x00\x19tEXtSoftware\x00gnome-screenshot\xef\x03\xbf>\x00\x00 \x00IDATx\x9c\xec\xddwtUU\xfe\xfe\xf1\xf7m\xb97\xbd7R(\x82t\x14\x01\xa5\xa8\x08"\xc5:6\x94\x19\xdb\x88\xfe\x14\x15\x1d\xa78\x96\xb1L\xb3|\xd5\xd1\xb1\x8b\r\x0bvF\x14\x0bM\x01\x1b\x88t!\x84\x1aH \xa4Wr\x93[\xcf\xef\x8f\x90k\x02\tI \t\x18\x9f\xd7ZY&\xe7\xec\xb3\xf7>\x91\xb0\x16O>{oSqq\xb1A+\xad\\\xb9\x92\xc8\xc8Hz\xf5\xea\xd5\xdaGE\x8ei[\xb7n\xa5\xbc\xbc\x9c\xa1C\x87\x1e\xed\xa9\x88\x88\x88\x88\x88\x88\x88H\x1b\x9a7o\x1e\xe7\x9f\x7f>n\xb7\xfbhO\xa5C\xcc\x9b7\x8fs\xce9\x07\x9f\xcfw\xd0\xbd\xcc\xccL\x06\x0c\x18\x80\xdf\xef\xc7\xef\xf7\xb7\xc9xf\xb3\x19\xb3\xd9\xcc\x86\r\x1b\xe8\xd3\xa7\xcfQ\x1b\xc7\xdc\xda\x0e\x0b\n\np\xb9\\\xa4\xa7\xa7\xb7\xc9\x04E\x8e%\xe9\xe9\xe9\xb8\\.\n\n\n\x8e\xf6TDDDDDDDD\xdaU[\x05\x90\xcd\xf5\xd5\x91\xe3X[\xdbann.c\xa3\xd1\xbf\xa7\xc74\xde\xf1\x80""""""""\xa2\t&))\tEEE\xe8\xeb\xeb\x83R\xa9Dnn\xae\xa7Cr\x89\xa7\xc71\x1a\xfd{zL\xe3\x1d\x93\x9dDDDDDDDD\x13LTT\x14\xa2\xa2\xa2<\x1d\xc6\x88yz\x1c\xa3\xd1\xbf\xa7\xc74\xdeq\x19;\x11\x11\x11\x11\x11\x11\x11\x11\x11y\x05&;\x89\x88\x88\x88\x88\x88\x88\x88\x88\xc8+0\xd9IDDDDDDDDD^\x81\xc9N"""""""""\xf2\nLv\x12\x11\x11\x11\x11\x11\x11\x11\x11\x91W`\xb2\x93\x88\x88\x88\x88\x88\x88\x88\x88\x88\xbc\x02\x93\x9dDDDDDDDDD\xe4\x15\x98\xec$"""""""""\xaf\xc0d\'\x11\x11\x11\x11\x11\x11\x11\x11\x11y\x05&;\x89\x88\x88\x88\x88\x88\x88\x88\x88\xc8+0\xd9IDDDDDDDDD^\x81\xc9N"""""""""\xf2\n\xff\x0f\xa0\xef4g\xb6\xaad\xbe\x00\x00\x00\x00IEND\xaeB`\x82', extra='')

(байты немного подрезал, максимальное количество знаков на тостере - 10к)
Сделать из этого файл можно тривиально:
if msg.tp == MsgType.binary:
                try:
                    with open('new_test_image.png', 'wb') as new_image_handle:
                        new_image_handle.write(decodebytes(msg.data))
                except Exception as e:
                    log.debug(e)

Но как видно из кода, имя файла и тип захардкожены, а надо узнавать эти данные от самого файла. как это можно сделать?
Если это важно, то использую WS из aiohttp
На входе от js:
f7a67f2699df417ba95c9240621af970.png
  • Вопрос задан
  • 506 просмотров
Решения вопроса 1
Daemon23RUS
@Daemon23RUS
У Вас в "куче" данных изображение в PNG формате, описание формата
\x89PNG\r\n\x1a\n - Заголовок, дальше идут чанки, бегло просматривая я увидел
IHDR - Основная информация об изображении
sBIT - Цветовая точность
tEXt - Содержит текст, у Вас "Software gnome-screenshot"
IDAT - Собственно данные
IEND - Конец PNG,
Далее следует несколько байт, но они не относятся к PNG
чанки tEXt содержат текстовую информацию, в том числе можно указать имя файла. Но это обязаннось генерирущего/передающего софта.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Rou1997
@Rou1997
Каждый формат имеет свои байты идентификации (сигнатуру), расположены в начале файла, обычно это первые 2-4 байта, для PNG это "\x89PNG", их здесь видно, читайте спецификации разных форматов и реализуйте определение каждого формата, который требуется.
Возможно, помогут готовые библиотеки, например для изображений, они поддерживают разные форматы, а значит, могут и определять их.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы