$@='NOT ';print"$@CORRUPTED"__DATA__ =®®”print"$@CORRUPTED"__DATA__ =®®”Ê®›~
Este programa contiene algunos octetos extraviados que no son válidos UTF-8. Como tal, se muestra como se ve en Windows-1252. (De manera predeterminada, si A Pear Tree ve un octeto no ASCII en un literal de cadena o similar, lo trata como un objeto opaco y no trata de entenderlo más allá de darse cuenta de cuál es su código de caracteres; este comportamiento puede ser cambiado a través de una declaración de codificación, pero el programa no tiene una. Por lo tanto, el programa está lógicamente en un "conjunto de caracteres compatible con ASCII no especificado".
Explicación
Un árbol de pera suma el programa, buscando la subcadena más larga que tiene un CRC-32 00000000
. (Si hay un empate, primero elige el octetobético). Luego, el programa se rota para colocarlo al inicio. Finalmente, el programa se interpreta como un lenguaje que es casi un superconjunto de Perl, definiendo algunas cosas que no están definidas en Perl para que funcionen de la misma manera que en Python (y con algunos cambios menores, por ejemplo, print
imprime una nueva línea final en A Pear Tree pero no en Perl) Este mecanismo (y el lenguaje en su conjunto) fue diseñado para el políglota y el endurecimiento por radiación. ; este no es el primero, pero definitivamente es el último.
En este programa, tenemos dos subcadenas notables que CRC-32 00000000
; todo el programa lo hace, y también lo hace print"$@CORRUPTED"__DATA__ =®®
por sí mismo (que aparece dos veces). Por lo tanto, si el programa es incorrupto, que va fijado $@
a NOT
y luego imprimirlo seguido por CORRUPTED
. Si el programa está dañado, el CRC-32 del programa en su conjunto no coincidirá, pero una de las secciones más cortas permanecerá sin corrupción. Cualquiera que sea girado al inicio del programa simplemente se imprimirá CORRUPTED
, al igual $@
que la cadena nula.
Una vez que se ha impreso la cadena, __DATA__
se usa para evitar que se ejecute el resto del programa. (Se me ocurre escribir esto que __END__
podría usarse en su lugar, lo que claramente ahorraría dos bytes. Pero también puedo publicar esta versión ahora, porque he pasado mucho tiempo verificándola, y una versión modificada tendría que ser re-verificado debido a los cambios de CRC, y aún no he puesto un gran esfuerzo en jugar golf con la "carga útil", así que quiero ver si alguien tiene otras mejoras en los comentarios que puedo incorporar al mismo tiempo. Tenga en cuenta que #
no funciona en la situación en la que un personaje está dañado en una nueva línea).
Quizás se esté preguntando cómo logré controlar el CRC-32 de mi código en primer lugar. Este es un truco matemático bastante simple basado en la forma en que se define CRC-32: toma el CRC-32 del código, lo escribe en orden little endian (el reverso del orden de bytes que normalmente se usa para el cálculo de CRC-32 programas) y XOR con 9D 0A D9 6D
. Luego agrega eso al programa, y tendrá un programa con un CRC-32 de 0. (Como el ejemplo más simple posible, la cadena nula tiene un CRC-32 de 0, por lo tanto9D 0A D9 6D
también tiene un CRC-32 de 0 .)
Verificación
Un Pear Tree puede manejar la mayoría de los tipos de mutaciones, pero supongo que "cambiado" significa "reemplazado por un octeto arbitrario". Es teóricamente posible (aunque poco probable en un programa tan corto) que pueda haber una colisión hash en algún lugar que conduzca a la ejecución del programa incorrecto, por lo que tuve que verificar a través de la fuerza bruta que todas las posibles sustituciones de octetos dejarían el programa funcionando correctamente. Aquí está el script de verificación (escrito en Perl) que utilicé:
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! ";