Ви секретний агент, який намагається спілкуватися зі своєю вітчизною. Звичайно, інформацію потрібно приховати, щоб ніхто не підпускав ваші повідомлення. Що б краще підходило, ніж кішка? Усі люблять смішні фотографії котів [потрібна цитата] , тому вони не підозрюють, що там ховається таємна інформація!
Надихнувшись алгоритмом, який гра Монако використовує для збереження інформації про рівень загальних рівнів , ваші завдання - написати програму, яка закодувала інформацію в найменш значущий біт кольорів зображення.
Формат кодування:
- Перші 24 біти визначають довжину решти закодованого байтового рядка в бітах
- Зображення читається зліва направо і зверху вниз, очевидно, починаючи з верхнього лівого пікселя
- Канали читаються від червоного до зеленого до синього
- Зчитується найменш значущий біт з кожного каналу
- Біти зберігаються в порядку Big Endian
Правила:
- У вашій програмі використовується один байт-рядок для кодування та одне ім'я файлу зображення для базового зображення
- Отримане зображення має вийти як справжній кольоровий PNG-файл
- Ви можете використовувати введення-виведення в будь-якій формі, яку вам подобається (ARGV, STDIN, STDOUT, запис / читання з файлу), поки ви заявляєте, як користуватися програмою
- Ви повинні вибрати випадкове зображення смішної кішки і закодувати її в програму, щоб показати, що ваша програма працює
- Ви можете припустити, що вам надається лише дійсний ввід, якщо кількість бітів недостатня, зображення не в справжньому кольоровому форматі, зображення не існує або подібні проблеми ви можете робити те, що вам потрібно
- Ви можете припустити, що надане зображення не містить альфа-каналу
- Довжина підраховується в байтах UTF-8 без BOM
Ви можете використовувати цей скрипт PHP для тестування свого рішення, вказуючи ім'я файлу PNG як перший аргумент командного рядка:
<?php
if ($argc === 1) die('Provide the filename of the PNG to read from');
$imageSize = @getimagesize($argv[1]);
if ($imageSize === false) die('Not a PNG file');
list($width, $height) = $imageSize;
$image = imagecreatefrompng($argv[1]);
$read = 0;
$bits = '';
for ($y = 0; $y < $height; $y++) {
for ($x = 0; $x < $width; $x++) {
$colorAt = imagecolorat($image, $x, $y);
$red = ($colorAt >> 16) & 0xFF;
$green = ($colorAt >> 8) & 0xFF;
$blue = ($colorAt >> 0) & 0xFF;
$bits .= ($red & 1).($green & 1).($blue & 1);
$read += 3;
if ($read == 24) {
$length = (int) bindec($bits);
$bits = '';
}
else if ($read > 24 && ($read - 24) > $length) {
$bits = substr($bits, 0, $length);
break 2;
}
}
}
if (strlen($bits) !== $length) die('Not enough bits read to fulfill the length');
$parts = str_split($bits, 8);
foreach ($parts as $part) {
echo chr(bindec($part));
}