Как стать автором
Обновить

Прячем текст в Bitmap

Время на прочтение 3 мин
Количество просмотров 40K
Доброго времени суток, уважаемый хабрачеловек. На хабре уже проскакивали мысли о том, как спрятать текст в bitmap-изображении. К сожалению, топиков на эту тему я не нашел и решил восполнить данный пробел. Под катом Вы найдете способ сокрытия текста в bitmap'е, а также реализацию на C#.

Постановка задачи

Спрятать произвольный текст в кодировке windows-1251 в 24-разрядный bitmap рисунок и излвечь его обратно без искажений.

Структура bmp-файла

Для начала напомню, что из себя представляет bitmap-файл. Я уверен, что Вы все это прекрасно знаете, просто будет нагляднее описывать алгоритм сокрытия текста на базе изложенного материала. И так. Любой bmp-файла состоит из четырех частей:
  1. Заголовок файла
  2. Заголовок изображения (может отсутствовать)
  3. Палитра (может отсутствовать)
  4. Само изображение
Заголовок файла содержит служебную информацию, в том числе разрядность рисунка. Кстати, для 24-разрядного рисунка палитра не используется. По скольку мы в задании четко обозначили, что будем работать только с 24-разрядными изображениями, то в идеале можно проверить входное изображение на соответствие требованиям.
Теперь перейдем, непосредственно, к самому изображению. Как Вам известно, формат bmp по умолчанию не предусматривает сжатие (хотя есть поддержка сжатия по алгоритму RLE). Таким образом каждый пиксел в нашем случае кодируется 24 битами, по байту на каждую компоненту цвета. Следовательно, мы можем закодировать ни больше ни меньше, а ровно 16777216 цветов. Для наглядности приведу рисунок:

Идея алгоритма сокрытия текста

Наверное, Вы уже догадались в чем идея. Дело все в том, что глаз среднестатистического человека (не профессионального художника или фотографа) различает намного меньше цветов, чем было указано выше. Ни в одной книге нет четкого ответа на вопрос, сколько все же цветов различает глаз, но самая большая цифра, которую я встретил — 10 млн. Отсюда следует, что несколько младших битов из восьми, отводимых на каждую компоненту цвета, можно позаимствовать для наших корыстных целей.
Немного цифр: для примера возьмем и нагло отнимем у RGB компонент по два младщих бита. То есть из 24 бит у нас останется 18, которыми можно закодировать ровно 262144 цветов. Теперь возьмем текст в кодировке windows-1251, в которой каждый символ представляется 8ю битами. Путем несложных математический вычислений получаем, что 3 символа можно сохранить в 4 пикселах. Таким образом, в картинке 1024x768, где 786432 пикселов можно сохранить 589824 символа. Неплохо, да? Для наглядности приведу две картинки. На первой исходное изображение, а на второй изображение, у которого младшие два бита каждой компоненты цвета заполнены текстом. Сразу оговорюсь, что изображения сконвертированы в png, чтобы пожалеть траффик.

Исходное изображение:

Изображение, содержащее текст

Если приглядется, то на втором изображении цвета кажутся тусклее. Да, это так. Но мы то с Вами знаем, что в представленном изображении что-то не так, а если бы не знали, то и не догадались бы, что в нем спрятан какой-то текст. Кстати, в изображении спрятана фраза «Hello World!!! =)» размноженная 100 раз.
Вот и все. Как Вы видите, идея предельно проста. Кстати говоря, представленный метод называется LSB (спасибо frol за подсказку). Напоследок, можете посмотреть реализацию на языке C#.

Реализация на C#

Представленная реализация не претендует на награду в стиле «Совершенный код», она лишь демонстрирует описанный алгоритм на практике. В данном случае я гнался не за красотой кода, а за наглядностью. Здесь Вы можете скачать архив и сходниками (~20 кб)

Примеры работы

Исходное изображение:

Изображение с 2 битами компоненты цвета, отведенными под текст

Изображение с 4 битами компоненты цвета, отведенными под текст

Изображение с 6 битами компоненты цвета, отведенными под текст

Спасибо за внимание!
Теги:
Хабы:
+4
Комментарии 10
Комментарии Комментарии 10

Публикации

Истории

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн