Bạn là một đặc vụ bí mật cố gắng giao tiếp với tổ quốc của bạn. Tất nhiên thông tin cần phải được ẩn đi để không ai nghe thấy tin nhắn của bạn. Điều gì sẽ phù hợp hơn một con mèo? Mọi người đều thích những bức ảnh hài hước về mèo [cần dẫn nguồn] , vì vậy họ sẽ không nghi ngờ thông tin bí mật ẩn trong đó!
Lấy cảm hứng từ thuật toán mà trò chơi mà Monaco sử dụng để lưu thông tin cấp độ của các cấp độ được chia sẻ , nhiệm vụ của bạn là viết một chương trình mã hóa thông tin thành một chút ít màu sắc quan trọng nhất của hình ảnh.
Định dạng mã hóa:
- 24 bit đầu tiên xác định độ dài của chuỗi byte được mã hóa còn lại tính bằng bit
- Hình ảnh được đọc từ trái sang phải và từ trên xuống dưới, rõ ràng bắt đầu từ pixel phía trên bên trái
- Các kênh được đọc từ đỏ sang xanh sang xanh
- Bit ít quan trọng nhất từ mỗi kênh được đọc
- Các bit được lưu theo thứ tự Big Endian
Quy tắc:
- Chương trình của bạn lấy một chuỗi byte đơn được mã hóa và một tên tệp hình ảnh duy nhất cho hình ảnh cơ sở
- Hình ảnh thu được phải được đưa ra dưới dạng tệp PNG màu thực
- Bạn có thể sử dụng I / O dưới bất kỳ hình thức nào bạn thích (ARGV, STDIN, STDOUT, viết / đọc từ một tệp), miễn là bạn nêu cách sử dụng chương trình của mình
- Bạn phải chọn một hình ảnh ngẫu nhiên của một con mèo vui nhộn và mã hóa chương trình của bạn vào đó để cho thấy rằng chương trình của bạn hoạt động
- Bạn có thể cho rằng bạn chỉ được cung cấp đầu vào hợp lệ, nếu số lượng bit không đủ, hình ảnh không ở định dạng màu thực, hình ảnh không tồn tại hoặc các vấn đề tương tự bạn có thể làm những gì bạn muốn
- Bạn có thể cho rằng hình ảnh được cung cấp không chứa bất kỳ kênh alpha nào
- Độ dài được tính bằng byte UTF-8 mà không cần BOM
Bạn có thể sử dụng tập lệnh PHP này để kiểm tra giải pháp của mình, cung cấp tên của tệp PNG làm đối số dòng lệnh đầu tiên:
<?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));
}