Detecta si tu programa ha sido mutado

16

Escriba un programa que finalice sin un error.

Si cualquier byte único se sustituye por otro byte, el programa debería generar

CORRUPTED
  • No lea su código fuente de un archivo
  • Su programa no debe producir ningún otro resultado

Este es el por lo que gana la respuesta más corta en bytes.

Editar: eliminado el requisito "NO CORRUPTO"

noɥʇʎԀʎzɐɹƆ
fuente
El endurecimiento por radiación tiene una serie de preguntas similares, pero no he encontrado ninguna similar a esta.
FryAmTheEggman
77
Para los votantes negativos: sospecho que esto es posible (si es muy difícil), si elige el idioma correcto. No cierre ni elimine la pregunta a menos que piense que hay algo mal aparte de ser imposible.
77
¿Qué significa cambiar ? Sustituido por otro byte?
Dennis
44
@ ais523 FWIW Desestimé el desafío porque parece apresuradamente escrito, no porque piense que es demasiado difícil.
Dennis
55
No es que nada esté claro, pero podría aclararse . Puede aclarar si se requiere un programa completo , agregar un programa de ejemplo e ilustrar todas las modificaciones posibles, mencionar cómo las sustituciones de un solo byte afectarían un archivo codificado UTF-8, agregar un script que pueda usarse para probar envíos, mencionar que el programa no debería tomar entrada, etc.
Dennis

Respuestas:

30

Un peral , 76 bytes

$@='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, printimprime 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 y ; 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!    ";

fuente
Un n bits CRC detectará cualquier error único no ya estalló de n bits. Las colisiones de hash son imposibles en el caso dado, no hay necesidad de verificación de fuerza bruta.
Rainer P.
@RainerP .: Soy consciente de que una mutación evitará el CRC para las porciones que originalmente tienen un CRC de 0 coincidente. Sin embargo, existe la posibilidad de que pueda introducir una nueva subcadena del código que tiene un CRC de 0; El propósito de la fuerza bruta es garantizar que eso no sucedió.