Jesteś tajnym agentem próbującym komunikować się ze swoją ojczyzną. Oczywiście informacje muszą być ukryte, aby nikt nie podsłuchiwał Twojej wiadomości. Co byłoby bardziej odpowiednie niż kot? Wszyscy uwielbiają śmieszne zdjęcia kotów [potrzebne źródło] , więc nie będą podejrzewać ukrytych tam tajnych informacji!
Zainspirowany algorytmem, którego gra Monako używa do zapisywania informacji o poziomie wspólnych poziomów , Twoim zadaniem jest napisanie programu, który zakodował informacje w najmniej znaczącym kolorze kolorów obrazu.
Format kodowania:
- Pierwsze 24 bity określają długość pozostałego zakodowanego ciągu bajtów w bitach
- Obraz jest odczytywany od lewej do prawej i od góry do dołu, oczywiście zaczynając od lewego górnego piksela
- Kanały są odczytywane z czerwonego na zielony na niebieski
- Odczytywany jest najmniej znaczący bit z każdego kanału
- Bity są zapisywane w kolejności Big Endian
Zasady:
- Twój program wymaga jednego ciągu bajtów do zakodowania i pojedynczej nazwy pliku obrazu dla obrazu podstawowego
- Powstały obraz musi być wyprowadzony jako plik PNG o prawdziwym kolorze
- Możesz używać We / Wy w dowolnej formie (ARGV, STDIN, STDOUT, zapis / odczyt z pliku), o ile podasz sposób korzystania z programu
- Musisz wybrać losowy obraz śmiesznego kota i zakodować w nim swój program, aby pokazać, że Twój program działa
- Możesz założyć, że podano tylko prawidłowe dane wejściowe, jeśli ilość bitów nie jest wystarczająca, obraz nie jest w prawdziwym formacie kolorów, obraz nie istnieje lub podobne problemy możesz zrobić, co chcesz
- Możesz założyć, że dostarczony obraz nie zawiera żadnego kanału alfa
- Długość jest liczona w bajtach UTF-8 bez BOM
Możesz użyć tego skryptu PHP do przetestowania rozwiązania, podając nazwę pliku PNG jako pierwszy argument wiersza poleceń:
<?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));
}