Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
jdvrif — Инструмент стеганографии для изображений JPG | Kitploit
Инструменты/GitHubGitHub/cleasbycode/jdvrif
Инструменты шифрования/дешифрованияЭксфильтрация данныхФорензикаСтеганографияКриптографияКонфиденциальность
GitHubcleasbycode/jdvrif

jdvrif

Инструмент стеганографии для изображений JPG

Репозиторий
691355 дней назадПроверено Kitploit

Популярное

Смотреть все →

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

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
# jdvrif

***jdvrif*** (*JPG Data Vehicle*) — это быстрый и простой в использовании инструмент стеганографии командной строки для сокрытия и извлечения файлов любого типа через **JPG**-изображение. ***Только для Linux***.

Ваш файл данных сжимается с помощью ***libdeflate/zlib***, затем шифруется с помощью ***XChaCha20-Poly1305*** (secretstream из ***libsodium***) ключом, производным от ***Argon2id*** из случайно сгенерированного ***восстановительного PIN-кода***, и наконец встраивается в изображение-контейнер. PIN-код отображается один раз, в конце работы команды ***conceal***, и нигде не сохраняется: без него скрытый файл невозможно восстановить.

Используя ***режим сокрытия по умолчанию***, вы можете скрыть файл любого типа, при этом итоговое изображение ограничено размером в ***2GiB***. Остальные режимы сокрытия для платформ и совместимые сайты социальных сетей (*перечисленные ниже*) имеют свои собственные ***гораздо меньшие*** ограничения по размеру и другие требования.

Существует [***веб-версия***](https://cleasbycode.co.uk/jdvrif/app/) ***jdvrif***, которую можно использовать сразу же как удобную альтернативу загрузке и компиляции исходного кода CLI. Загрузка файлов через веб-интерфейс ограничена **20MiB**.

Для тех, кто интересуется этим языком, также доступен экспериментальный порт на ***Rust*** [***jdvrif-rs***](https://github.com/CleasbyCode/jdvrif-rs). Он совместим по формату: любая из сборок может восстановить изображения, созданные другой.

***jdvrif*** частично основан на ***[реализованной технике](https://www.vice.com/en/article/bj4wxm/tiny-picture-twitter-complete-works-of-shakespeare-steganography)*** исследователя в области безопасности ***[David Buchanan](https://www.da.vidbuchanan.co.uk/).***

![Demo Image](https://raw.githubusercontent.com/CleasbyCode/jdvrif/main/demo_image/jrif_043b7c551.jpg)  
*Демонстрационное изображение: **"A place of concealment"** / ***PIN: 7912872750612437051****

## Как jdvrif скрывает данные

В отличие от распространённого метода стеганографии [***LSB***](https://ctf101.org/forensics/what-is-stegonagraphy/) (*Least Significant Bit*), при котором данные скрываются в пикселях изображения-контейнера, ***jdvrif*** в основном прячет данные внутри ***сегментов приложения*** ***JPG***-изображения (ICC, EXIF, XMP и т. д.).

| Режим сокрытия | Куда помещаются данные | Где можно поделиться итоговым изображением |
| --- | --- | --- |
| *(без опции)* | сегменты профиля APP2/ICC | X-Twitter, Tumblr, Mastodon, Pixelfed, PostImage, ImgBB, ImgPile, Flickr |
| ***-b*** | сегменты EXIF / Photoshop / XMP с обрамлением | только ***Bluesky*** |
| ***-r*** | DCT-коэффициенты JPEG (***QIM***) | только ***Reddit*** |
| ***-x*** | DCT-коэффициенты JPEG (***J-UNIWARD/STC***) | только ***X-Twitter*** |

Два платформенных исключения из метода хранения в сегментах по умолчанию — это ***Reddit*** и ***X-Twitter***. У обеих есть собственный режим сокрытия, и ни один из этих режимов вообще не использует сегменты метаданных: ***-r*** и ***-x*** переносят полезную нагрузку в DCT-коэффициентах ***JPG***-изображения.

***Reddit*** перекодирует загруженные изображения и отбрасывает сегменты метаданных, на которые опирается режим по умолчанию, поэтому ***-r*** — единственный режим, который там работает. ***X-Twitter*** сохраняет один небольшой сегмент ICC, поэтому режим по умолчанию на этой платформе всё ещё работает, но только для крошечной полезной нагрузки.

Для режима сокрытия ***Reddit*** (***-r***) мы используем [***метод стеганографии QIM***](https://www.google.com/search?q=QIM+steganography+method&sourceid=chrome&ie=UTF-8&source=chrome.ctxt) (*Quantization Index Modulation в области DCT-коэффициентов JPEG*), поскольку это единственный метод хранения, который в настоящее время работает для ***Reddit***. Изображение-контейнер перекодируется в baseline Q75 4:2:0, а полезная нагрузка переносится в его блоках DCT яркости.

Чтобы максимизировать ёмкость хранилища для платформы ***Reddit***, используйте изображение-контейнер с большими размерами, **2048x2048**, **4096x4096**, **8192x8192 (макс.)** и т. д.

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

Хотя платформа ***X-Twitter*** может использовать метод по умолчанию, предоставляемый ***jdvrif***, при котором данные скрываются в сегментах APP2/ICC, ***X-Twitter*** ограничивает это одним сегментом ICC с максимальным размером всего **~10KiB**.

Чтобы вместить больше этих **~10 КиБ**, используйте режим сокрытия платформы ***X-Twitter*** (***-x***). Он полностью отказывается от сегментов метаданных — в ICC-профиль ничего не записывается — и вместо этого использует [***адаптивный метод стеганографии J-UNIWARD с кодированием Syndrome-Trellis (STC)***](https://www.google.com/search?q=adaptive+J-UNIWARD+steganography+method+with+Syndrome-Trellis+Coding+(STC)). Контейнер транскодируется в прогрессивный 4:2:0 с качеством, производным от исходного (с ограничением **Q97**).

Чтобы максимизировать ёмкость хранилища для платформы ***X-Twitter***, используйте контейнерное изображение высокого качества/детализации с большими размерами, **1024x1024**, **2048x2048**, **4096x4096 (макс.)** и т. д.

Носители ***-r*** и ***-x*** шифруют ваши данные и привязывают их местоположение к вашему PIN-коду восстановления с помощью ***Argon2id***, но встраивание всё равно изменяет статистику DCT изображения, поэтому целенаправленный стегоанализ может выявить, что изображение содержит скрытые данные.

Изображения ***-r*** и ***-x***, созданные с помощью ***jdvrif v9.0***, остаются восстановимыми, но ***v9.0*** не может восстановить изображения ***-r*** или ***-x***, созданные с помощью ***v9.1***.

Оба режима DCT переносят гораздо меньше данных, чем режим по умолчанию, поэтому используйте ***capsize*** для измерения контейнерного изображения перед выбором полезной нагрузки (см. [Проверка ёмкости](#checking-capacity-with-capsize)).

## Требования и компиляция (Linux)

Для сборки требуются **CMake 3.20 или новее**, `flock` из **util-linux**, а также **Ninja** (предпочтительно) или **Make**. Компилятор должен быть **GCC 14 или новее** либо **Clang 18 или новее** в паре со стандартной библиотекой C++23, реализующей такие возможности, как `std::format` и `std::print`. Требуемые нативные библиотеки: **libsodium**, **libjpeg-turbo** (*оба API — `turbojpeg` и `libjpeg`*), **zlib** и **libdeflate**. **OpenMP** необязателен: при его наличии он распараллеливает проход вычисления стоимости J-UNIWARD для ***-x***.

```console
$ sudo apt update
$ sudo apt install g++ cmake ninja-build util-linux libsodium-dev libturbojpeg0-dev libjpeg-dev zlib1g-dev libdeflate-dev

$ g++ --version   # confirm the reported version is 14 or newer

$ chmod +x compile_jdvrif.sh
$ ./compile_jdvrif.sh

$ sudo cp jdvrif /usr/bin
```

Если в вашем дистрибутиве GCC 14 поставляется как версионированный пакет, установите `g++-14` и выполните сборку командой `CXX=g++-14 ./compile_jdvrif.sh`.

Обёртка хранит объектные файлы с отслеживанием зависимостей в `src/build/`, поэтому при последующих запусках пересобирается только изменённое, а опубликованный бинарный файл `jdvrif` заменяется только после полной успешной сборки. Задайте `JDVRIF_JOBS=<count>`, чтобы изменить ограничение параллелизма (по умолчанию: число CPU, но не более 8), `JDVRIF_BUILD_DIR=<path>` для использования отдельного кэша сборки или `BUILD_MODE=sanitize` для сборки с ASan/UBSan.

## Использование

```console
$ jdvrif

Usage: jdvrif conceal [-b|-r|-x] <cover_image> <secret_file>
       jdvrif recover <cover_image>
       jdvrif capsize [-r|-x] <cover_image>
       jdvrif --info
```

Запустите `jdvrif --info`, чтобы получить полное встроенное руководство по режимам, параметрам платформ и ограничениям размера.

```console
$ jdvrif conceal your_cover_image.jpg your_secret_file.doc

Platform compatibility for output image:-

 ✓ X-Twitter
 ✓ Tumblr
 ✓ Mastodon
 ✓ Pixelfed
 ✓ PostImage
 ✓ ImgBB
 ✓ ImgPile
 ✓ Flickr

Recovery PIN: [***2166776980318349924***]

Important: Keep your PIN safe, so that you can extract the hidden file.


Saved "file-embedded" JPG image: jrif_4e87c566c.jpg (143029 bytes).

Complete!

$ jdvrif recover jrif_4e87c566c.jpg

PIN: *******************

Extracted hidden file: your_secret_file.doc (6165 bytes).

Complete! Please check your file.

```

Аргументы ***режима*** jdvrif:

  ***conceal*** - Сжимает, шифрует и встраивает ваш файл секретных данных в ***JPG*** изображение-обложку.  
  ***recover*** - Расшифровывает, распаковывает и извлекает скрытый файл данных из ***JPG*** изображения-обложки (*требуется PIN-код восстановления*).  
  ***capsize*** - Сообщает ёмкость носителя изображения-обложки для режима ***-r*** или ***-x***. Изображение не сохраняется.

Требования к изображению-обложке:

● Только JPEG, не менее **400x400** пикселей, и либо в оттенках серого, либо в цвете YCbCr — изображения CMYK/YCCK необходимо сначала преобразовать в RGB.

● Верхние размеры по умолчанию и для ***-b*** составляют **4096x4096px**; ***-r*** использует **8192x8192px**, а ***-x*** также ограничен **4096x4096px**.

● Режим по умолчанию (*без опции*) также отклоняет изображения-обложки, оценочное качество JPEG которых выше **Q97**; пересохраните изображение с более низким качеством, если оно отклонено.

Требования к файлу секретных данных:

● Встраиваемое имя файла должно быть не длиннее **20 байт**, не должно начинаться с `.` или `-` или заканчиваться пробелом или `.`, и должно быть корректным UTF-8 без управляющих символов или символов двунаправленного форматирования, а также без любого из `/ \ : * ? " < > |`. Имя хранится в изображении и восстанавливается при ***recover***.

● Ваш файл данных сжимается перед шифрованием, за исключением распознанных уже сжатых типов файлов (`.zip`, `.7z`, `.mp4`, `.jpg`, `.png` и т. д.). В режимах по умолчанию и ***-b*** эти типы пропускают сжатие только если они больше **10MiB**; в режимах ***-r*** и ***-x*** они всегда его пропускают. Для всего остального, предназначенного для небольшого ограничения платформы, рассмотрите возможность сначала сжать его самостоятельно (*zip, rar, 7z и т. д.*), чтобы вы знали его точный сохранённый размер.

## Совместимые платформы

\******************   
Примечание: ***Bluesky*** теперь по умолчанию сохраняет изображения как ***WEBP***. 

Чтобы сохранить изображение как ***JPG***, чтобы вы по-прежнему могли восстановить скрытые данные с помощью ***jdvrif***:-  

Сначала нажмите на изображение в посте, чтобы открыть его, затем щёлкните по изображению правой кнопкой мыши. В меню выберите ***Открыть изображение в новой вкладке***.  

Перейдите на новую вкладку и в адресной строке переместитесь в конец адреса и добавьте ***@jpg***, затем нажмите Enter.  
Щёлкните по изображению правой кнопкой мыши и в меню выберите ***Сохранить изображение...***  

Теперь ваше изображение должно быть загружено как ***JPG***, которое будет работать с ***jdvrif***.
         
Если вам нужен инструмент для сокрытия данных с использованием изображений ***WEBP*** для публикации в ***Bluesky***, вы можете использовать мой CLI-инструмент стеганографии для ***WEBP*** ***[wbpdv](https://github.com/CleasbyCode/wbpdv)***  
\******************

*Ограничение размера при публикации измеряется по ***суммарному*** размеру ***изображения-обложки*** + ***сжатого файла данных:****  

● ***Flickr*** (**200 МиБ**), ***ImgPile*** (**100 МиБ**), ***ImgBB*** (**32 МиБ**), ***PostImage*** (**32 МиБ**), ***Pixelfed*** (**15 МиБ**).

*Ограничение размера измеряется ***только*** по ***размеру сжатого файла данных:****  

● ***Mastodon*** (**~6MiB**), ***Tumblr*** (**~64KiB**), ***X-Twitter*** (**~10KiB / метод по умолчанию**).  

Например, с ***Mastodon***, если ваше изображение-обложка имеет размер **1MiB**, вы всё ещё можете встроить файл данных вплоть до предела **~6MiB**.

**Другое: платформы с собственным режимом сокрытия:**

● ***Bluesky*** (***опция -b***). Готовый «*со встроенным файлом*» ***JPG*** не должен превышать **2 000 000 байт (~1,9MiB)**, поэтому изображение-обложка и сжатый файл данных делят один бюджет. Сам сжатый файл данных не должен превышать **~171KiB**. Изображение-обложка, уже имеющее размер 2 000 000 байт, не оставляет места вообще, поэтому держите обложку меньше предела как минимум на размер вашего сжатого файла данных. Для публикации этих изображений в ***Bluesky*** требуется скрипт «***create_bsky_post.py***». *Подробнее об этом скрипте ниже на странице.*

● ***Reddit*** (***опция -r***). Изображение-обложка и файл данных должны быть каждый не больше **20MiB**, но фактическая ёмкость носителя изображения-обложки ***гораздо меньше*** и зависит от его размеров. Используйте `jdvrif capsize -r`, чтобы измерить её.

● ***X-Twitter*** (***опция -x***). Обложка и файл данных должны быть не больше **5MiB** каждая, а обложка не должна превышать **4096x4096** пикселей. Фактическая ёмкость носителя ***намного меньше*** и зависит от качества и размеров изображения. Используйте `jdvrif capsize -x`, чтобы её измерить.

В режимах по умолчанию и ***-b*** обложка также оптимизируется без потерь перед использованием и после этого шага не должна превышать **4MiB**.

Для платформ, таких как ***X-Twitter***, ***Reddit*** и ***Tumblr***, которые имеют небольшие ограничения на размер данных, возможно, стоит ориентироваться на данные, которые хорошо сжимаются, например текстовые файлы и т. п.

https://github.com/user-attachments/assets/af330d09-f65d-4f75-8290-883078be34b3

https://github.com/user-attachments/assets/fc454d42-0240-4864-b44b-ce5ef7cfd94c

## Проверка ёмкости с помощью capsize

***capsize*** подготавливает обложку точно так же, как это сделал бы ***conceal***, а затем сообщает, какой объём зашифрованных данных она может вместить. На диск ничего не записывается. Используйте ***-r*** для носителя ***Reddit*** и ***-x*** для носителя ***X-Twitter*** (***-x*** используется по умолчанию, если не указана ни одна опция).

```console
$ jdvrif capsize -r basic_img_large_dims.jpg

Reddit capacity check for conceal -r mode only.

Cover Image: 384KiB, 8192x8192, Baseline YCbCr 4:2:0, Standard Q75 quantization (C3).

Theoretical C3 capacity limit for this cover image:                    436906 bytes (~426KiB).
Conservative maximum compressed capacity with a 20-character filename: 436792 bytes (~426KiB).
Recommended  maximum compressed capacity with a 20-character filename: 435768 bytes (~425KiB).
```

Указанная цифра — это общая ёмкость зашифрованного ***конверта***, а не необработанный лимит секретного файла: имя файла, метаданные шифрования и восстановления занимают от 95 до 114 байт для полезной нагрузки в одном фрейме, а более крупные полезные нагрузки добавляют накладные расходы на фрейминг. Не стремитесь к теоретическому пределу — где позволяет ёмкость, держите сжатый объём полезной нагрузки как минимум на **1KiB** ниже консервативного максимума. Проверка размера, выполняемая ***conceal***, является авторитетной.

## Платформенные опции режима conceal

Чтобы создавать совместимые "*data-concealed*" изображения ***JPG*** для публикации на платформе ***Reddit***, необходимо использовать опцию ***-r*** с режимом ***conceal***.
  ```console
  $ jdvrif conceal -r my_image.jpg hidden.doc
```

  Эти изображения совместимы только для публикации на ***Reddit***. Ваш встроенный файл данных будет потерян при публикации на другой платформе.  
  
  При сохранении/скачивании изображения с ***Reddit*** обязательно нажмите на изображение в посте, чтобы полностью развернуть его перед сохранением.  

https://github.com/user-attachments/assets/ead3c34c-dd9a-4018-9ea3-0746fbdfdb8b

Чтобы создать совместимые "*data-concealed*" изображения ***JPG*** для публикации на платформе ***X-Twitter*** с использованием метода стеганографии J-UNIWARD, необходимо использовать опцию ***-x*** с режимом ***conceal***.
  ```console
  $ jdvrif conceal -x my_image.jpg hidden.doc
```

  Эти изображения совместимы только для публикации в ***X-Twitter***. Ваш файл со встроенными данными будет утерян при публикации на другой платформе.  
  
  При сохранении/скачивании изображения из ***X-Twitter*** обязательно нажмите на изображение в посте, чтобы полностью развернуть его перед сохранением.  

Чтобы создать совместимые "*file-embedded*" изображения ***JPG*** для публикации на платформе ***Bluesky***, необходимо использовать опцию ***-b*** с режимом ***conceal***.
  ```console
  $ jdvrif conceal -b my_image.jpg hidden.doc
```

  Эти изображения совместимы только для публикации в ***Bluesky***. Ваш встроенный файл данных будет удалён, если опубликовать его на другой платформе.
 
  Также необходимо использовать скрипт Python [create_bsky_post.py](https://github.com/CleasbyCode/jdvrif/blob/main/src/bsky/create_bsky_post.py) (находится в папке ***src/bsky*** репозитория) для публикации изображения в ***Bluesky***.
  Это не сработает, если вы публикуете изображения в ***Bluesky*** через браузерный сайт или мобильное приложение.  

  Чтобы использовать скрипт, вам нужно создать [***app password***](https://bsky.app/settings/app-passwords) в вашей учётной записи ***Bluesky***. Передавайте свои учётные данные через переменные окружения, а не в командной строке, где они были бы видны другим локальным пользователям с помощью таких инструментов, как `ps`:

  ```console
  $ pip install -r bsky/requirements.txt

  $ export ATP_AUTH_HANDLE='you.bsky.social'
  $ read -rsp 'Bluesky app password: ' ATP_AUTH_PASSWORD && export ATP_AUTH_PASSWORD

  $ python3 bsky/create_bsky_post.py \
      --image jrif_4e87c566c.jpg \
      --alt-text "alt-text here [optional]" \
      "standard post text here [required]"

  $ unset ATP_AUTH_PASSWORD
```

  Полный набор параметров (*несколько изображений, ответы, цитируемые посты, карточки ссылок*) и описание того, от чего защищает усиленный форк скрипта, см. в [src/bsky/README.md](https://github.com/CleasbyCode/jdvrif/blob/main/src/bsky/README.md).

https://github.com/user-attachments/assets/1daef508-d304-491f-bfe2-2cdbb5d62081

## Тесты

Каждый тестовый скрипт в `src/tests` принимает в качестве аргумента бинарный файл для проверки:

```console
$ bash tests/run_golden_tests.sh --bin ./jdvrif        # recover pre-built images with known PINs
$ bash tests/run_roundtrip_tests.sh --bin ./jdvrif     # fresh conceal/recover round-trips
$ bash tests/run_security_smoke.sh --bin ./jdvrif      # negative-path and boundary checks
$ bash tests/run_reddit_tests.sh --bin ./jdvrif        # -r QIM carrier
$ bash tests/run_twitter_tests.sh --bin ./jdvrif       # -x J-UNIWARD/STC carrier
$ bash tests/run_io_security_tests.sh --bin ./jdvrif   # input-size bounds, PIN signal/job-control handling
$ bash tests/run_jpeg_safety_tests.sh                  # JPEG parser/decoder safety (builds its own test binary)
$ bash tests/run_bsky_tests.sh                         # Bluesky posting helper
```

## Стороннее программное обеспечение и ресурсы

  ### Основные приложения

  - [libsodium](https://github.com/jedisct1/libsodium) — криптографическая генерация случайных чисел, вывод ключей Argon2id
  и секретные потоки XChaCha20-Poly1305. Динамически компонуется как системная библиотека.
      
      Лицензия: [ISC License](https://github.com/jedisct1/libsodium/blob/master/LICENSE)
    
      Copyright (c) 2013–2026 Frank Denis.
    
 - [libjpeg-turbo](https://github.com/libjpeg-turbo/libjpeg-turbo) — обработка JPEG и преобразование без потерь. Динамически компонуется как системная библиотека.

      Это программное обеспечение частично основано на работе Independent JPEG Group.

      Лицензии: [Independent JPEG Group License, Modified BSD 3-Clause License,
      и zlib License](https://github.com/libjpeg-turbo/libjpeg-turbo/blob/2.1.5/LICENSE.md).

      Copyright © 1991–2020 Thomas G. Lane и Guido Vollbeding.
   
      Copyright © 2009–2023 D. R. Commander. Все права защищены.
   
      Copyright © 2015 Viktor Szathmáry. Все права защищены.
   
  - [zlib](https://github.com/madler/zlib) — потоковая компрессия и декомпрессия zlib. Динамически компонуется как системная библиотека.

    Лицензия: [zlib License](https://github.com/madler/zlib/blob/develop/LICENSE)
    
    Copyright (C) 1995–2026 Jean-loup Gailly и Mark Adler.

  - [libdeflate](https://github.com/ebiggers/libdeflate) — быстрая компрессия всего буфера в формате zlib. Динамически компонуется как системная библиотека.

    Лицензия: [MIT](https://github.com/ebiggers/libdeflate/blob/master/COPYING)
    
    Copyright 2016 Eric Biggers.
    
    Copyright 2024 Google LLC.

  ### Включённый код и ресурсы

  - [Compact ICC Profiles](https://github.com/saucecontrol/Compact-ICC-Profiles) — встроенный ICC-профиль,
  совместимый с Adobe.

    Лицензия: [CC0 1.0 Universal](https://github.com/saucecontrol/Compact-ICC-Profiles/blob/master/license)

  ### Необязательный помощник для публикации в Bluesky

  - Bryan Newbold / ATProto Hacker Cookbook — create_bsky_post.py — основа для [ответвлённого](https://gist.github.com/CleasbyCode/1eb678ca1fa1975b1c1e20aeec33637e) помощника для публикации в Bluesky (src/bsky/create_bsky_post.py). 
    Для справки см. [копию из Cookbook](https://github.com/bluesky-social/cookbook/blob/main/python-bsky-post/create_bsky_post.py)

    Лицензия: [CC0 1.0 Universal](https://github.com/bluesky-social/cookbook/blob/main/LICENSE-CC0).

  - Requests — HTTP-запросы и запросы к API Bluesky.

    Лицензия: [Apache 2.0](https://github.com/psf/requests/blob/main/LICENSE) / [NOTICE](https://github.com/psf/requests/blob/main/NOTICE)
    
    Copyright 2019 Kenneth Reitz.

  - Beautiful Soup 4 — синтаксический анализ HTML и метаданных Open Graph.

    Лицензия: [MIT](https://pypi.org/project/beautifulsoup4/)
    
    Copyright (c) Leonard Richardson.

  - Pillow — проверка изображений, размеры и обработка соотношения сторон.

    Лицензия: [MIT-CMU](https://github.com/python-pillow/Pillow/blob/main/LICENSE)
    
    PIL copyright © 1997–2011 Secret Labs AB и © 1995–2011 Fredrik Lundh и участники.
    
    Pillow copyright © 2010 Jeffrey “Alex” Clark и участники.
    
##
Скачать инструмент