$@='NOT ';print"$@CORRUPTED"__DATA__ =®®”print"$@CORRUPTED"__DATA__ =®®”Ê®›~
Ця програма містить кілька бродячих октетів, які не є дійсними UTF-8. Таким чином, він показаний так, як це виглядає в Windows-1252. (За замовчуванням, якщо Pear Tree бачить октет, що не є ASCII, у рядковому літералі чи тому подібне, він трактує його як непрозорий об'єкт і не намагається зрозуміти це, крім того, що не знає про те, що його код символу; така поведінка може бути змінюється за допомогою декларації кодування, але в програмі її немає. Отже, програма логічно в "не визначеному наборі символів, сумісних з ASCII". Усі октети, що не належать до ASCII, все одно є у коментарях, тому це насправді не має значення.)
Пояснення
Грушеве дерево перевіряє суми програми, шукаючи найдовшу підрядку, у якої є CRC-32 00000000
. (Якщо є краватка, вона спочатку підбирає октетбетично.) Потім програма обертається, щоб поставити її на старт. Нарешті, програма інтерпретується як мова, що є майже суперсетью Perl, визначаючи кілька речей, які не визначені в Perl, щоб працювати так само, як і в Python (і з кількома незначними змінами, наприклад, print
друкує остаточний новий рядок у Pear Tree але не в Перлі). Цей механізм (і мова в цілому) був розроблений для проблем поліглоту та радіаційного загартування ; це не перше, але, безумовно, останнє.
У цій програмі у нас є дві помітні підрядки, до яких CRC-32 00000000
; вся програма робить, і так робить print"$@CORRUPTED"__DATA__ =®®
сама (що з’являється двічі). Таким чином , якщо програма неушкоджена, вона буде встановлена $@
на , NOT
а потім роздрукувати його наступним CORRUPTED
. Якщо програма пошкоджена, то CRC-32 програми в цілому не збігатиметься, але один з коротших розділів залишиться непошкодженим. Незалежно від того, хто з них повернутий до початку програми, він просто надрукує CORRUPTED
, як $@
і нульовий рядок.
Після друку рядка __DATA__
використовується для запобігання запуску решти програми. (Мені здається, що я написав це, що __END__
міг би бути використаний натомість, що дозволило б заощадити два байти. Але я можу також опублікувати цю версію зараз, тому що я витратив купу часу на її перевірку, і модифікована версія повинна бути повторно підтверджений через зміни CRC, і я ще не доклав великих зусиль для того, щоб розіграти «корисну навантаження» для гольфу, тому я хочу побачити, чи є у когось інші вдосконалення в коментарях, які я можу включити одночасно. Зверніть увагу, що #
це не працює в ситуації, коли персонаж пошкоджений у новий рядок.)
Вам може бути цікаво, як мені вдалося в першу чергу контролювати CRC-32 свого коду. Це досить простий математичний трюк, заснований на тому, як визначено CRC-32: ви берете CRC-32 коду, записуєте його в порядок малих ендіантів (зворотній порядок байт, який зазвичай використовується для обчислення CRC-32 програми) та XOR с 9D 0A D9 6D
. Потім ви додаєте це до програми, і у вас буде програма з CRC-32 0. (Як найпростіший приклад, нульова рядок має CRC-32 0, таким чином, 9D 0A D9 6D
також є CRC-32 0 .)
Перевірка
Дерево груші може обробляти більшість видів мутацій, але я припускаю, що "змінено" означає "замінено на довільний октет". Теоретично можливо (хоча навряд чи в програмі ця коротка програма), що десь може статися хеш-зіткнення, що призводить до неправильної роботи програми, тому мені довелося через грубу силу перевірити, що всі можливі заміни октету залишать програму працювати коректно. Ось сценарій підтвердження (написаний на Perl), який я використав:
use 5.010;
use IPC::Run qw/run/;
use warnings;
use strict;
undef $/;
$| = 1;
my $program = <>;
for my $x (0 .. (length $program - 1)) {
for my $a (0 .. 255) {
print "$x $a \r";
my $p = $program;
substr $p, $x, 1, chr $a;
$p eq $program and next;
alarm 4;
run [$^X, '-M5.010', 'apeartree.pl'], '<', \$p, '>', \my $out, '2>', \my $err;
if ($out ne "CORRUPTED\n") {
print "Failed mutating $x to $a\n";
print "Output: {{{\n$out}}}\n";
print "Errors: {{{\n$err}}}\n";
exit;
}
}
}
say "All OK! ";