$@='NOT ';print"$@CORRUPTED"__DATA__ =®®”print"$@CORRUPTED"__DATA__ =®®”Ê®›~
Chương trình này chứa một vài octet đi lạc không hợp lệ UTF-8. Như vậy, nó được hiển thị như trong Windows-1252. (Theo mặc định, nếu Cây lê nhìn thấy một octet không phải ASCII trong một chuỗi ký tự hoặc giống như nó coi nó như một đối tượng mờ đục và không cố gắng hiểu nó ngoài việc nhận thức được mã ký tự của nó là gì; hành vi này có thể là đã thay đổi thông qua một khai báo mã hóa nhưng chương trình không có. Vì vậy, chương trình này nằm trong "bộ ký tự tương thích ASCII không xác định".
Giải trình
Cây lê kiểm tra chương trình, tìm kiếm chuỗi con dài nhất có CRC-32 00000000
. (Nếu có một chiếc cà vạt, nó sẽ chọn quãng tám trước.) Sau đó, chương trình sẽ được xoay để đặt nó vào lúc bắt đầu. Cuối cùng, chương trình được hiểu là một ngôn ngữ gần như là siêu ngôn ngữ của Perl, xác định một vài điều không xác định trong Perl để hoạt động giống như trong Python (và với một vài thay đổi nhỏ, ví dụ như print
in một dòng mới cuối cùng trong A Pear Tree nhưng không ở Perl). Cơ chế này (và toàn bộ ngôn ngữ) được thiết kế cho các vấn đề làm cứng polyglot và bức xạ ; Đây không phải là cái trước, nhưng nó chắc chắn là cái sau.
Trong chương trình này, chúng tôi có hai chuỗi con đáng chú ý mà CRC-32 tới 00000000
; toàn bộ chương trình thực hiện, và nó cũng vậy print"$@CORRUPTED"__DATA__ =®®
(xuất hiện hai lần). Như vậy, nếu chương trình không được sửa chữa, nó sẽ được đặt $@
thành NOT
và sau đó in nó theo sau CORRUPTED
. Nếu chương trình bị hỏng, thì toàn bộ CRC-32 của chương trình sẽ không khớp, nhưng một trong những phần ngắn hơn sẽ vẫn chưa được sửa chữa. Bất cứ cái nào được quay vào đầu chương trình sẽ chỉ in CORRUPTED
, như $@
là chuỗi null.
Khi chuỗi đã được in, __DATA__
được sử dụng để ngăn phần còn lại của chương trình chạy. (Tôi nghĩ rằng việc viết này __END__
có thể được sử dụng thay thế, điều này rõ ràng sẽ tiết kiệm được hai byte. Nhưng tôi cũng có thể đăng phiên bản này ngay bây giờ, vì tôi đã dành rất nhiều thời gian để xác minh nó, và một phiên bản sửa đổi sẽ phải xác minh lại do những thay đổi của CRC và tôi chưa nỗ lực rất nhiều để đánh golf "tải trọng", vì vậy tôi muốn xem có ai có những cải tiến khác trong các nhận xét mà tôi có thể kết hợp cùng một lúc không. Lưu ý rằng #
không hoạt động trong trường hợp một nhân vật bị hỏng trong một dòng mới.)
Bạn có thể tự hỏi làm thế nào tôi quản lý để kiểm soát CRC-32 trong mã của tôi ngay từ đầu. Đây là một mẹo toán học khá đơn giản dựa trên cách xác định CRC-32: bạn lấy CRC-32 của mã, viết nó theo thứ tự cuối nhỏ (ngược lại với thứ tự byte thường được sử dụng trong tính toán CRC-32 chương trình) và XOR với 9D 0A D9 6D
. Sau đó, bạn thêm nó vào chương trình và bạn sẽ có một chương trình có CRC-32 bằng 0. (Ví dụ đơn giản nhất có thể, chuỗi null có CRC-32 là 0, do đó 9D 0A D9 6D
cũng có CRC-32 là 0 .)
xác minh
Cây lê có thể xử lý hầu hết các loại đột biến, nhưng tôi cho rằng "đã thay đổi" có nghĩa là "được thay thế bằng một octet tùy ý". Về mặt lý thuyết là có thể (mặc dù không có khả năng trong một chương trình ngắn) rằng có thể xảy ra xung đột băm ở đâu đó dẫn đến chương trình chạy sai, vì vậy tôi phải kiểm tra thông qua lực lượng vũ trang rằng tất cả các thay thế octet có thể sẽ khiến chương trình hoạt động chính xác. Đây là tập lệnh xác minh (được viết bằng Perl) mà tôi đã sử dụng:
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! ";