Оригинальное изображение Как-то мне пришла идея, что было бы неплохо иметь способ отправлять секретные сообщения замаскированные как обычные изображения. Результат я назвал Jailbird. Ладно-ладно, я шучу, это просто эксперимент. Сегодня я хотел бы показать вам, как можно сохранить "Гамлета" Шекспира в изображении практически незаметно. (Хе-хе, я думаю, у многих возникала проблема контрабанды Гамлета куда-либо...) Исходный код доступен на Github: https://github.com/ClanCatsStation/Jailbird Чтобы начать мы должны знать, как много места нам понадобится. (Размер имеет значение ;)). Я взял "Гамлета" и поместил его в файл hamlet.txt. Потом создал php скрипт, который назвал size.php. Чтобы убрать из вызова скрипта php в командной строке установим интерпретатор для запуска: Чтобы получить данные, читаем контент из STDIN: Теперь запустим команду: Получим длину строки / количество байт равное 175132. Попробуем заархивировать: И получим: 70681 байт. Jailbird может хранить 1 бит на цвет на пиксель. Итого 565'448 бит, что означает, что нам нужно 188'483 пикселей. Или изображение размером по-крайней мере 435x435 пикселей. Добавим эти расчеты в скрипт size.php, что позволит легко узнать, какого размера изображение нам понадобится. Почему я добавил 16 байт к длине контента? Нам нужно определять момент окончания данных по наличию какой-то последовательности знаков, я решил, что это будет строка @endOfJailbird;, которая и содержит 16 символов. Собственно то, для чего мы здесь собрались. (А то я что-то разошелся) Самый простой способ внедрить данные в изображение, подумал я, это сконвертировать их в бинарную строку. Функция ord возвращает байт в его ASCII представление. Затем при помощи функции decbin конвертируем полученное число в бинарное и обернем в sprintf для сохранения ведущих нулей. На выходе получим довольно большую строку из нулей и единиц Тут нам понадобится изображение, в которое мы будем записывать. Передадим путь к изображению первым аргументом в скрипт inject.php. Проверим, имеем ли мы доступ к изображению: Команда записи будет иметь вид: Изображение cats.png возьмем из (оригинального, прим. пер.) КДПВ:  Теперь запустим цикл: Этот код просто проходит последовательно по цветам пикселей и сохраняет изменение цветов обратно в пиксель. А вот самая важная штука: Это короткая строка кода говорит нам о текущем цвете текущего пикселя четный он или нечентный. А $bit = $data[$dataIndex]; сообщает нам, четным или нечетным должно быть текущее значение цвета. Таким образом мы создаем еще один слой данных поверх изображения просто округляя значения цвета до четного или нечетного числа. Теперь, все что нам нужно сделать, это обновить значения цветов: И собственно все! Осталось только сохранить изображение: Обратный процесс — извлечение данных достаточно просто, после того, как мы разобрались с внедрением. Создаем новый файл extract.php. Скрипт извлечения данных также будет получать путь к изображению как аргумент. Затем у нас почти такое же итерирование с тем отличием, что нам не надо ничего модифицировать, только проверяем, четное значение или нет. В переменной $data содержатся сырые данные, которые мы должны сконвертировать в байты: Полученный контент заархивирован, и заказнчивается значением endOfJailbird. Мы можем отбросить все, что идет после него: Как результат мы можем запустить скрипт: И получить прекрасную Шекспировскую пьесу обратно. Если поместить 2 изображения рядом, вероятно, разница не будет, хотя вы можете заметить небольшое размытие:  Но есть еще пара моментов: Дело в том, что мы сохраняем изображение без сжатия, иначе это приведет к потере данных. В то время как исходный файл весит 307 KB, после сохранения данных получаем 759 KB. Но я, к сожалению, не вижу вариантов решения этой проблемы. Также, при отправке изображения в, например, facebook, reddit или twitter изображение будет сжато на серверах этих сервисом и данные, скорее всего, будут потеряны. В конечном итоге это был довольно веселый эксперимент, я хорошо провел эти несколько часов над ним. Надеюсь вы тоже найдете эту идею интересной и что вы не потратили это время зря. (В ином случае: хе-хе, я украл твое время!) Never Gonna Give You Up Тыжпрограммист