คุณเป็นสายลับพยายามสื่อสารกับบ้านเกิดเมืองนอนของคุณ แน่นอนว่าข้อมูลจะต้องถูกซ่อนไว้ดังนั้นจึงไม่มีใครปิดบังข้อความของคุณ อะไรจะเหมาะกว่าแมว ทุกคนชอบรูปแมวตลก ๆ[อ้างอิงที่จำเป็น]ดังนั้นพวกเขาจะไม่สงสัยว่ามีข้อมูลลับซ่อนอยู่ในนั้น!
แรงบันดาลใจจากอัลกอริธึมที่เกมโมนาโกใช้ในการบันทึกข้อมูลระดับของระดับที่ใช้ร่วมกันมันเป็นหน้าที่ของคุณในการเขียนโปรแกรมที่เข้ารหัสข้อมูลลงในสีที่มีนัยสำคัญน้อยที่สุดของภาพ
รูปแบบการเข้ารหัส:
- 24 บิตแรกจะกำหนดความยาวของไบต์ที่เข้ารหัสที่เหลือเป็นบิต
- ภาพจะถูกอ่านจากซ้ายไปขวาและจากบนลงล่างเห็นได้ชัดว่าเริ่มจากพิกเซลซ้ายบน
- ช่องจะอ่านจากสีแดงเป็นสีเขียวเป็นสีน้ำเงิน
- อ่านบิตที่มีนัยสำคัญน้อยที่สุดจากแต่ละช่อง
- การบันทึกบิตจะถูกจัดเรียงตาม Big Endian
กฎ:
- โปรแกรมของคุณใช้การเข้ารหัสไบต์เดียวและชื่อไฟล์ภาพเดียวสำหรับภาพพื้นฐาน
- ภาพที่ได้จะต้องออกมาเป็นไฟล์ PNG สีจริง
- คุณสามารถใช้ I / O ในรูปแบบใดก็ได้ที่คุณต้องการ (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));
}