Sie sind ein Geheimagent, der versucht, mit Ihrem Vaterland zu kommunizieren. Natürlich müssen die Informationen verborgen sein, damit niemand Ihre Nachricht abfängt. Was wäre besser geeignet als eine Katze? Jeder liebt lustige Bilder von Katzen [Zitat benötigt] , damit sie nicht den Verdacht haben, dass sich dort geheime Informationen verstecken!
Inspiriert von dem Algorithmus, den Monaco verwendet, um die Level-Informationen von gemeinsam genutzten Levels zu speichern , ist es Ihre Aufgabe, ein Programm zu schreiben, das Informationen in das niedrigstwertige Bit der Farben eines Bildes codiert.
Kodierungsformat:
- Die ersten 24 Bits bestimmen die Länge der verbleibenden codierten Bytefolge in Bits
- Das Bild wird von links nach rechts und von oben nach unten gelesen, wobei offensichtlich mit dem oberen linken Pixel begonnen wird
- Die Kanäle werden von rot über grün nach blau ausgelesen
- Das niedrigstwertige Bit von jedem Kanal wird gelesen
- Bits werden in Big Endian-Reihenfolge gespeichert
Regeln:
- Ihr Programm benötigt eine einzelne zu codierende Bytefolge und einen einzelnen Bilddateinamen für das Basisbild
- Das resultierende Bild muss als True-Color-PNG-Datei ausgegeben werden
- Sie können I / O in beliebiger Form verwenden (ARGV, STDIN, STDOUT, Schreiben / Lesen aus einer Datei), sofern Sie angeben, wie Sie Ihr Programm verwenden möchten
- Sie müssen ein zufälliges Bild einer lustigen Katze auswählen und Ihr Programm darin kodieren, um zu zeigen, dass Ihr Programm funktioniert
- Sie können davon ausgehen, dass Sie nur eine gültige Eingabe erhalten, wenn die Anzahl der Bits nicht ausreicht, das Bild nicht im Echtfarbenformat vorliegt, das Bild nicht vorhanden ist oder ähnliche Probleme auftreten, die Sie möglicherweise ausführen, was Sie möchten
- Sie können davon ausgehen, dass das bereitgestellte Bild keinen Alphakanal enthält
- Die Länge wird in UTF-8-Bytes ohne Stückliste gezählt
Sie können dieses PHP-Skript verwenden, um Ihre Lösung zu testen. Geben Sie als erstes Befehlszeilenargument den Namen der PNG-Datei an:
<?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));
}