$@='NOT ';print"$@CORRUPTED"__DATA__ =®®”print"$@CORRUPTED"__DATA__ =®®”Ê®›~
โปรแกรมนี้มีออคเต็ตเรย์ไม่กี่อันที่ไม่ถูกต้อง UTF-8 ดังนั้นจะปรากฏตามที่ปรากฏใน Windows-1252 (โดยค่าเริ่มต้นหากต้นแพร์เห็นอ็อกเท็ตที่ไม่ใช่ ASCII ในสตริงตัวอักษรหรือสิ่งที่คล้ายกันถือว่าเป็นวัตถุทึบแสงและไม่พยายามที่จะเข้าใจมันเกินกว่าจะรู้ตัวว่าโค้ดตัวนั้นคืออะไรพฤติกรรมนี้สามารถ เปลี่ยนผ่านการประกาศการเข้ารหัส แต่โปรแกรมไม่มีดังนั้นโปรแกรมจึงมีเหตุผลใน "ชุดอักขระที่เข้ากันได้กับ ASCII ที่ไม่ระบุ" ส่วนออคเต็ตที่ไม่ใช่ ASCII ทั้งหมดอยู่ในข้อคิดเห็นดังนั้นมันไม่สำคัญเลย)
คำอธิบาย
ลูกแพร์ต้นไม้ checksums โปรแกรมที่กำลังมองหาสตริงย่อยที่ยาวที่สุดที่มี CRC-32 00000000
ของ (หากมีการเสมอกันจะเลือก octetbetically ก่อน) จากนั้นโปรแกรมจะหมุนเพื่อเริ่มต้น ในที่สุดโปรแกรมแปลเป็นภาษาที่เกือบจะเป็นภาษาชุดใหญ่ของ Perl โดยกำหนดบางสิ่งที่ไม่ได้กำหนดใน Perl ให้ทำงานเหมือนกับใน Python (และมีการเปลี่ยนแปลงเล็กน้อยเช่นprint
พิมพ์บรรทัดสุดท้ายใน A Pear Tree แต่ไม่ใช่ใน Perl) กลไกนี้ (และภาษาที่เป็นทั้ง) ได้รับการออกแบบสำหรับการพูดได้หลายภาษาและรังสีแข็งปัญหา นี่ไม่ใช่อดีต แต่มันหลังอย่างแน่นอน
ในโปรแกรมนี้เรามีสองสตริงเรื่องน่าทึ่งที่ CRC-32 00000000
; โปรแกรมทั้งหมดทำและดำเนินการprint"$@CORRUPTED"__DATA__ =®®
เอง (ซึ่งปรากฏสองครั้ง) ดังนั้นหากโปรแกรมที่ไม่เสียหายก็จะตั้ง$@
ไปแล้วพิมพ์ตามด้วยNOT
CORRUPTED
หากโปรแกรมเสียหาย CRC-32 ของโปรแกรมโดยรวมจะไม่ตรงกัน แต่หนึ่งในส่วนที่สั้นลงจะยังคงไม่ถูกขัดจังหวะ ไม่ว่าอันใดที่หมุนไปที่จุดเริ่มต้นของโปรแกรมจะพิมพ์ออกCORRUPTED
มาเช่นเดียว$@
กับสตริงว่าง
เมื่อสตริงถูกพิมพ์__DATA__
จะถูกใช้เพื่อป้องกันไม่ให้ส่วนที่เหลือของโปรแกรมทำงาน (มันข้ามความคิดของฉันที่เขียนสิ่งนี้ซึ่ง__END__
สามารถนำมาใช้แทนซึ่งจะช่วยประหยัดสองไบต์อย่างชัดเจน แต่ฉันอาจโพสต์เวอร์ชันนี้ในขณะนี้เพราะฉันใช้เวลาในการตรวจสอบความถูกต้องและรุ่นที่แก้ไขจะต้องเป็น ตรวจสอบอีกครั้งเนื่องจากการเปลี่ยนแปลงของ CRC และฉันยังไม่ได้ใช้ความพยายามอย่างมากในการเล่น "น้ำหนักบรรทุก" ดังนั้นฉันต้องการดูว่าใครมีการปรับปรุงอื่น ๆ ในความคิดเห็นที่ฉันสามารถรวมไว้ในเวลาเดียวกัน โปรดทราบว่า#
ไม่สามารถใช้งานได้ในสถานการณ์ที่อักขระเสียหายในการขึ้นบรรทัดใหม่)
คุณอาจสงสัยว่าฉันควบคุม CRC-32 ของรหัสของฉันได้อย่างไรตั้งแต่แรก นี่เป็นกลอุบายทางคณิตศาสตร์ที่ค่อนข้างง่ายโดยใช้วิธีที่ CRC-32 กำหนด: คุณนำรหัส CRC-32 มาเขียนในลำดับเล็ก ๆ น้อย ๆ (กลับลำดับไบต์ที่ปกติใช้ในการคำนวณ CRC-32 โปรแกรม) และ XOR ด้วย9D 0A D9 6D
และแฮคเกอร์ด้วย จากนั้นคุณต่อท้ายโปรแกรมและคุณจะมีโปรแกรมที่มี CRC-32 เป็น 0 (เป็นตัวอย่างที่ง่ายที่สุดที่เป็นไปได้สตริง null มี CRC-32 จาก 0 ดังนั้นจึง9D 0A D9 6D
มี CRC-32 จาก 0 .)
การตรวจสอบ
ต้นแพร์สามารถจัดการการกลายพันธุ์ส่วนใหญ่ได้ แต่ฉันสมมติว่า "เปลี่ยน" หมายถึง "แทนที่ด้วย octet โดยพลการ" เป็นไปได้ในทางทฤษฎี (แม้ว่าจะไม่น่าเป็นไปได้ในโปรแกรมนี้ในระยะสั้น) ว่าอาจมีการชนกันของแฮชบางแห่งที่นำไปสู่การทำงานของโปรแกรมที่ไม่ถูกต้องดังนั้นฉันต้องตรวจสอบผ่านแรงเดรัจฉานว่า นี่คือสคริปต์ตรวจสอบ (เขียนด้วย Perl) ที่ฉันใช้:
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! ";