Rileva se il tuo programma è stato modificato


16

Scrivi un programma che termina senza errori.

Se un singolo byte è sostituito da qualsiasi altro byte, il programma dovrebbe essere emesso

CORRUPTED
  • Non leggere il codice sorgente da un file
  • Il tuo programma non dovrebbe produrre altri output

Questo è quindi vince la risposta più breve in byte.

Modifica: rimosso il requisito "NON CORRUPTATO"


l'indurimento delle radiazioni ha una serie di domande simili, ma non ne ho trovate di simili.
FryAmTheEggman,

7
Ai downvoter: sospetto che sia possibile (se molto difficile), se scegli la lingua giusta. Ti preghiamo di non chiudere o eliminare la domanda a meno che tu non pensi che ci sia qualcosa di sbagliato nell'essere diverso dall'essere impossibile.

7
Cosa significa cambiato ? Sostituito da un altro byte?
Dennis,

4
@ ais523 FWIW Ho votato in negativo la sfida perché sembra scritta in fretta, non perché penso che sia troppo difficile.
Dennis,

5
Non è che qualcosa non è chiaro, ma potrebbe essere reso più chiaro . Puoi chiarire se è necessario un programma completo , aggiungere un programma di esempio e illustrare tutte le possibili modifiche, menzionare in che modo le sostituzioni a byte singolo influirebbero su un file codificato UTF-8, aggiungere uno script che può essere utilizzato per testare gli invii, menzionare che il programma non dovrebbe ricevere input, ecc.
Dennis

Risposte:


30

Un albero di pere , 76 byte

$@='NOT ';print"$@CORRUPTED"__DATA__ =®®”print"$@CORRUPTED"__DATA__ =®®”Ê®›~

Questo programma contiene alcuni ottetti vaganti che non sono validi UTF-8. Come tale, viene mostrato come appare in Windows-1252. (Per impostazione predefinita, se A Pear Tree vede un ottetto non ASCII in una stringa letterale o simile, lo tratta come un oggetto opaco e non cerca di capirlo oltre a essere consapevole di quale sia il suo codice carattere; questo comportamento può essere modificato tramite una dichiarazione di codifica ma il programma non ne ha uno. Quindi il programma è logicamente in "set di caratteri ASCII non specificato". Tutti gli ottetti non ASCII sono comunque nei commenti, quindi non importa.)

Spiegazione

A Pear Tree controlla il programma, cercando la sottostringa più lunga che abbia un CRC-32 di 00000000. (Se c'è un pareggio, seleziona prima l'ottetbetico.) Quindi il programma viene ruotato per metterlo all'inizio. Infine, il programma viene interpretato come un linguaggio che è quasi un superset di Perl, definendo alcune cose che non sono definite in Perl per funzionare allo stesso modo di in Python (e con alcune piccole modifiche, ad esempio printstampa una nuova riga finale in A Pear Tree ma non in Perl). Questo meccanismo (e il linguaggio nel suo insieme) è stato progettato per problemi di e ; questo non è il primo, ma è sicuramente il secondo.

In questo programma, abbiamo due notevoli sottostringhe a cui CRC-32 00000000; l'intero programma lo fa, e così fa print"$@CORRUPTED"__DATA__ =®®da solo (che appare due volte). Pertanto, se il programma non è danneggiato, verrà impostato $@su NOT e quindi lo stampa seguito da CORRUPTED. Se il programma è danneggiato, il CRC-32 del programma nel suo insieme non riuscirà a corrispondere, ma una delle sezioni più brevi rimarrà non corrotta. Qualunque sia ruotato all'inizio del programma verrà stampato CORRUPTED, così come $@la stringa nulla.

Una volta stampata la stringa, __DATA__viene utilizzata per impedire il resto del programma in esecuzione. (Mi viene in mente di scrivere questo che __END__potrebbe essere usato invece, il che salverebbe chiaramente due byte. Ma potrei anche pubblicare questa versione ora, perché ho trascorso un sacco di tempo a verificarlo, e una versione modificata dovrebbe essere ricontrollato a causa delle modifiche del CRC e non ho ancora fatto grandi sforzi nel golfare il "payload", quindi voglio vedere se qualcuno ha altri miglioramenti nei commenti che posso incorporare allo stesso tempo. Nota che #non funziona nella situazione in cui un personaggio è corrotto in una nuova riga.)

Potresti chiederti come sono riuscito a controllare il CRC-32 del mio codice in primo luogo. Questo è un trucco matematico abbastanza semplice basato sul modo in cui è definito CRC-32: prendi il CRC-32 del codice, lo scrivi in ​​ordine little-endian (il contrario dell'ordine dei byte che viene normalmente utilizzato dal calcolo CRC-32 programmi) e XOR con 9D 0A D9 6D. Quindi lo aggiungi al programma e avrai un programma con un CRC-32 di 0. (Come l'esempio più semplice possibile, la stringa null ha un CRC-32 di 0, quindi 9D 0A D9 6Dha anche un CRC-32 di 0 .)

Verifica

Un albero di pere può gestire la maggior parte delle mutazioni, ma suppongo che "cambiato" significhi "sostituito con un ottetto arbitrario". È teoricamente possibile (anche se improbabile in un programma così breve) che potrebbe esserci una collisione di hash da qualche parte che porta a un programma errato in esecuzione, quindi ho dovuto verificare con la forza bruta che tutte le possibili sostituzioni di ottetti avrebbero lasciato il programma funzionare correttamente. Ecco lo script di verifica (scritto in Perl) che ho usato:

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!    ";

Un n bit CRC in grado di rilevare ogni singolo errore non più scoppio di n bit. Le collisioni di hashish sono impossibili nel caso dato, non è necessaria una verifica della forza bruta.
Rainer P.

@RainerP .: Sono consapevole che una mutazione impedirà al CRC per le porzioni che originariamente hanno un CRC pari a 0. Tuttavia, c'è la possibilità che possa introdurre una nuova sottostringa del codice che ha un CRC di 0; lo scopo della forza bruta è garantire che ciò non accada.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.