$@='NOT ';print"$@CORRUPTED"__DATA__ =®®”print"$@CORRUPTED"__DATA__ =®®”Ê®›~
Este programa contém alguns octetos perdidos que não são válidos UTF-8. Como tal, é mostrado como parece no Windows-1252. (Por padrão, se A Pear Tree vê um octeto não ASCII em uma string literal ou semelhante, trata-o como um objeto opaco e não tenta entendê-lo além de estar ciente de qual é seu código de caractere; esse comportamento pode ser alterado através de uma declaração de codificação, mas o programa não possui uma. Portanto, o programa está logicamente em "conjunto de caracteres não especificado compatível com ASCII". Todos os octetos não ASCII estão nos comentários de qualquer maneira, portanto, isso realmente não importa.)
Explicação
Uma árvore de pera soma o programa, procurando a substring mais longa que possui um CRC-32 00000000
. (Se houver um empate, ele escolhe o octetbeticamente primeiro.) Em seguida, o programa é rotacionado para colocá-lo no início. Finalmente, o programa é interpretado como uma linguagem que é quase um superconjunto do Perl, definindo algumas coisas indefinidas no Perl para que funcionem da mesma maneira que no Python (e com algumas pequenas alterações, por exemplo, print
imprime uma nova linha final em A Pear Tree mas não em Perl). Esse mecanismo (e a linguagem como um todo) foi projetado para problemas poliglotas e de proteção contra radiação ; este não é o primeiro, mas é definitivamente o último.
Neste programa, temos duas substrings notáveis para as quais o CRC-32 00000000
; o programa inteiro faz, e o faz print"$@CORRUPTED"__DATA__ =®®
sozinho (que aparece duas vezes). Como tal, se o programa não estiver corrompido, ele será definido $@
como NOT
e depois será impresso CORRUPTED
. Se o programa estiver corrompido, o CRC-32 do programa como um todo falhará ao corresponder, mas uma das seções mais curtas permanecerá incorreta. O que for girado para o início do programa será impresso CORRUPTED
, assim como $@
a sequência nula.
Depois que a string é impressa, __DATA__
é usada para impedir a execução do restante do programa. (Me passa pela cabeça escrever isso que __END__
poderia ser usado em vez disso, o que claramente salvaria dois bytes. Mas também posso postar esta versão agora, porque passei muito tempo verificando-a e uma versão modificada teria que ser foi verificada novamente devido às alterações da CRC e ainda não dediquei um grande esforço ao golfe da "carga útil", então quero ver se alguém tem outras melhorias nos comentários que posso incorporar ao mesmo tempo. Observe que #
não funciona na situação em que um personagem está corrompido em uma nova linha.)
Você pode estar se perguntando como eu consegui controlar o CRC-32 do meu código em primeiro lugar. Este é um truque matemático bastante simples, baseado na maneira como o CRC-32 é definido: você pega o CRC-32 do código, escreve-o em ordem little-endian (o inverso da ordem de bytes que normalmente é usado no cálculo do CRC-32 programas) e XOR com 9D 0A D9 6D
. Em seguida, você anexa isso ao programa e terá um programa com um CRC-32 de 0. (Como o exemplo mais simples possível, a cadeia nula tem um CRC-32 de 0, 9D 0A D9 6D
também possui um CRC-32 de 0 .)
Verificação
Uma árvore de pêra pode lidar com a maioria dos tipos de mutações, mas estou assumindo que "alterado" significa "substituído por um octeto arbitrário". É teoricamente possível (embora improvável em um programa tão curto) que possa haver uma colisão de hash em algum lugar que leve ao programa errado em execução, então eu tive que verificar por força bruta que todas as possíveis substituições de octetos deixariam o programa funcionando corretamente. Aqui está o script de verificação (escrito em Perl) que eu usei:
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! ";