Sei un agente segreto che cerca di comunicare con la tua patria. Ovviamente le informazioni devono essere nascoste in modo che nessuno intercetta il messaggio. Cosa sarebbe più adatto di un gatto? Tutti adorano immagini divertenti di gatti [citazione necessaria] , quindi non sospetteranno che informazioni segrete si nascondano lì dentro!
Ispirato dall'algoritmo utilizzato dal gioco Monaco per salvare le informazioni sui livelli dei livelli condivisi , è compito tuo scrivere un programma che codifichi le informazioni nei bit meno significativi dei colori di un'immagine.
Formato di codifica:
- I primi 24 bit determinano la lunghezza della stringa di byte codificata rimanente in bit
- L'immagine viene letta da sinistra a destra e dall'alto verso il basso, ovviamente a partire dal pixel in alto a sinistra
- I canali vengono letti dal rosso al verde al blu
- Viene letto il bit meno significativo di ciascun canale
- I bit vengono salvati nell'ordine di Big Endian
Regole:
- Il programma richiede una singola stringa di byte da codificare e un singolo nome file di immagine per l'immagine di base
- L'immagine risultante deve essere emessa come un file PNG a colori reali
- È possibile utilizzare l'I / O in qualsiasi forma (ARGV, STDIN, STDOUT, scrivere / leggere da un file), purché si dichiari come utilizzare il programma
- Devi scegliere un'immagine casuale di un gatto divertente e codificare il tuo programma in esso per mostrare che il tuo programma funziona
- Puoi supporre che ti venga fornito un input valido, se la quantità di bit non è sufficiente, l'immagine non è nel formato di colore vero, l'immagine non esiste o problemi simili potresti fare quello che vuoi
- Si può presumere che l'immagine fornita non contenga alcun canale alfa
- La lunghezza viene contata in byte UTF-8 senza distinta base
Puoi usare questo script PHP per testare la tua soluzione, fornire il nome del file PNG come primo argomento della riga di comando:
<?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));
}