Programınızın mutasyona uğramış olup olmadığını tespit edin


16

Hatasız sonlanan bir program yazın.

Herhangi bir tek bayt başka bir bayt ile değiştirilirse, program çıktı almalıdır

CORRUPTED
  • Kaynak kodunuzu bir dosyadan okuma
  • Programınız başka çıktı üretmemelidir

Bu yani bayt en kısa cevap kazanır.

Düzenleme: "NOT CORRUPTED" gereksinimi kaldırıldı


radyasyon sertleştirmenin benzer soruları vardır, ancak buna benzer herhangi bir soru bulamadım.
FryAmTheEggman

7
Downvoter'lara: Doğru dili seçerseniz bunun mümkün olduğunu düşünüyorum (çok zorsa). İmkansız olmanın dışında bir sorun olduğunu düşünmüyorsanız lütfen soruyu kapatmayın veya silmeyin.

7
Değişen ne anlama geliyor? Başka bir bayt tarafından değiştirildi mi?
Dennis

4
@ ais523 FWIW Çok zor olduğunu düşündüğüm için değil, aceleyle yazılmış gibi göründüğü için mücadeleyi reddettim.
Dennis

5
Bir şey belirsiz değil, ama daha açık hale getirilebilir . Tam bir programın gerekli olup olmadığını açıklığa kavuşturabilir , örnek bir program ekleyebilir ve tüm olası değişiklikleri gösterebilir, tek baytlı ikamelerin UTF-8 kodlu bir dosyayı nasıl etkileyeceğini söyleyebilir, gönderimleri test etmek için kullanılabilecek bir komut dosyası ekleyebilir, programın girdi almamalı vb.
Dennis

Yanıtlar:


30

Armut Ağacı , 76 bayt

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

Bu program, geçerli UTF-8 olmayan birkaç sokak sekizli içerir. Bu nedenle, Windows-1252'de göründüğü gibi gösterilir. (Varsayılan olarak, Armut Ağacı ASCII olmayan bir oktet'i bir dize değişmezinde veya benzeri bir şekilde görürse, bunu opak bir nesne olarak görür ve karakter kodunun ne olduğunun farkında olmanın ötesinde anlamaya çalışmazsa, bu davranış olabilir kodlama bildirimi ile değiştirildi, ancak programın bir tane yok. Bu nedenle program mantıksal olarak "belirtilmemiş ASCII uyumlu karakter kümesi" nde. ASCII olmayan tüm sekizliler zaten yorumlarda bulunuyor, bu yüzden gerçekten önemli değil.)

açıklama

Bir Armut Ağacı, CRC-32 olan en uzun alt dizeyi arayan programı kontrol eder 00000000. (Bir kravat varsa, ilk önce sekizli olarak seçer.) Sonra program başlangıçta koymak için döndürülür. Son olarak, program Perl'in neredeyse üst kümesi olan bir dil olarak yorumlanır ve Perl'de tanımlanmamış birkaç şeyi Python'da olduğu gibi çalışır (ve birkaç küçük değişiklikle, örneğin printA Armut Ağacı'nda son bir satır yazdırır) ancak Perl'de değil). Bu mekanizma (ve bir bütün olarak dil) ve problemleri için tasarlanmıştır ; bu eskisi değil, ama kesinlikle ikincisi.

Bu programda, CRC-32'nin iki önemli alt dizesi var 00000000; tüm program yapar ve print"$@CORRUPTED"__DATA__ =®®kendi başına da (iki kez görünür). Program bozulmamış ise Gibi, bu belirleriz $@için NOT ve daha sonra takip yazdırmak CORRUPTED. Program bozulursa, programın bir bütün olarak CRC-32'si eşleşemez, ancak daha kısa bölümlerden biri bozulmadan kalır. Hangisi programın başlangıcına döndürülürse , boş dize CORRUPTEDgibi yazdırılacaktır $@.

Dize yazdırıldıktan sonra, __DATA__programın geri kalanının çalışmasını önlemek için kullanılır. (Bunun __END__yerine kullanılabilecek, bunu iki bayt açıkça kaydedecek şekilde yazmak aklımı kesiyor . Ama şimdi bu sürümü de gönderebilirim, çünkü bunu doğrulamak için bir sürü zaman geçirdim ve değiştirilmiş bir sürüm CRC değişiklikleri nedeniyle yeniden doğruladı ve henüz "yük" golf için büyük bir çaba koymak değil, bu yüzden herkes aynı anda dahil yorumlarda başka gelişmeler olup olmadığını görmek istiyorum. #Bir karakterin satırsonuna bozuk olduğu durumda çalışmadığını unutmayın .)

İlk başta kodumun CRC-32'sini nasıl kontrol edebildiğimi merak ediyor olabilirsiniz. Bu, CRC-32'nin tanımlanma şekline dayanan oldukça basit bir matematik hilesidir: kodun CRC-32'sini alırsınız, küçük endian düzeninde yazarsınız (normalde CRC-32 hesaplaması tarafından kullanılan bayt sırasının tersi) programları) ve XOR ile 9D 0A D9 6D. Daha sonra bunu programa eklersiniz ve CRC-32 değeri 0 olan bir programınız olur. (Mümkün olan en basit örnek olarak, boş dizenin CRC-32 değeri 0'dır, dolayısıyla 9D 0A D9 6DCRC-32 değeri 0'dır. .)

Doğrulama

Armut Ağacı mutasyonların çoğunu işleyebilir, ancak "değiştirilmiş" ifadesinin, keyfi bir sekizlinin yerini aldığı anlamına geldiğini varsayıyorum. Teorik olarak (bir programda bu kadar kısa olmasa da) yanlış programın çalışmasına neden olan bir karmaşanın olması olasıdır, bu yüzden kaba kuvvet aracılığıyla tüm olası sekizli ikamelerin programı doğru çalışmasına izin vermesini kontrol etmek zorunda kaldım. Kullandığım doğrulama betiği (Perl ile yazılmış):

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

Bir n- bit CRC, n bitten daha uzun olmayan herhangi bir hata patlamasını tespit edecektir. Verilen durumda karma çarpışmalar imkansızdır, kaba kuvvet doğrulamasına gerek yoktur.
Rainer P.

@RainerP .: Bir mutasyonun, CRC değeri 0 olan bölümler için CRC'yi engelleyeceğini biliyorum. Bununla birlikte, CRC'si 0 olan kodun yeni bir alt dizesini ekleyebilme olasılığı vardır; kaba kuvvetin amacı bunun gerçekleşmediğini garanti etmektir.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.