งงงวยกันเถอะ
เยื้อง:
main(_) {
_^448 && main(-~_);
putchar(--_%64
? 32 | -~7[__TIME__-_/8%8][">'txiZ^(~z?"-48] >> ";;;====~$::199"[_*2&8|_/64]/(_&2?1:8)%8&1
: 10);
}
การแนะนำตัวแปรในการแก้ให้หายยุ่ง:
main(int i) {
if(i^448)
main(-~i);
if(--i % 64) {
char a = -~7[__TIME__-i/8%8][">'txiZ^(~z?"-48];
char b = a >> ";;;====~$::199"[i*2&8|i/64]/(i&2?1:8)%8;
putchar(32 | (b & 1));
} else {
putchar(10); // newline
}
}
ทราบว่า-~i == i+1
เนื่องจากการเติมเต็มสอง ดังนั้นเราจึงมี
main(int i) {
if(i != 448)
main(i+1);
i--;
if(i % 64 == 0) {
putchar('\n');
} else {
char a = -~7[__TIME__-i/8%8][">'txiZ^(~z?"-48];
char b = a >> ";;;====~$::199"[i*2&8|i/64]/(i&2?1:8)%8;
putchar(32 | (b & 1));
}
}
ตอนนี้โปรดทราบว่าa[b]
เป็นเช่นเดียวกับb[a]
และใช้การ-~ == 1+
เปลี่ยนแปลงอีกครั้ง:
main(int i) {
if(i != 448)
main(i+1);
i--;
if(i % 64 == 0) {
putchar('\n');
} else {
char a = (">'txiZ^(~z?"-48)[(__TIME__-i/8%8)[7]] + 1;
char b = a >> ";;;====~$::199"[(i*2&8)|i/64]/(i&2?1:8)%8;
putchar(32 | (b & 1));
}
}
การแปลงการวนซ้ำเป็นลูปและการแอบทำได้ง่ายขึ้นอีกเล็กน้อย:
// please don't pass any command-line arguments
main() {
int i;
for(i=447; i>=0; i--) {
if(i % 64 == 0) {
putchar('\n');
} else {
char t = __TIME__[7 - i/8%8];
char a = ">'txiZ^(~z?"[t - 48] + 1;
int shift = ";;;====~$::199"[(i*2&8) | (i/64)];
if((i & 2) == 0)
shift /= 8;
shift = shift % 8;
char b = a >> shift;
putchar(32 | (b & 1));
}
}
}
เอาต์พุตนี้หนึ่งอักขระต่อหนึ่งการวนซ้ำ อักขระทุกตัวที่ 64 จะแสดงบรรทัดใหม่ มิฉะนั้นจะใช้ตารางข้อมูลคู่หนึ่งเพื่อหาว่าจะเอาท์พุทอะไรและใส่อักขระ 32 (ช่องว่าง) หรืออักขระ 33 (a !
) ตารางแรก ( ">'txiZ^(~z?"
) คือชุด 10 บิตแมปที่อธิบายลักษณะที่ปรากฏของอักขระแต่ละตัวและตารางที่สอง ( ";;;====~$::199"
) เลือกบิตที่เหมาะสมที่จะแสดงจากบิตแมป
ตารางที่สอง
int shift = ";;;====~$::199"[(i*2&8) | (i/64)];
ขอเริ่มต้นด้วยการตรวจสอบตารางที่สอง i/64
คือหมายเลขบรรทัด (6 ถึง 0) และi*2&8
คือ 8 iff i
คือ 4, 5, 6 หรือ 7 mod 8
if((i & 2) == 0) shift /= 8; shift = shift % 8
เลือกตัวเลขฐานแปดสูง (สำหรับi%8
= 0,1,4,5) หรือตัวเลขฐานแปดต่ำ (สำหรับi%8
= 2,3,6,7) ของค่าตาราง ตารางเลื่อนลงมาเป็นแบบนี้:
row col val
6 6-7 0
6 4-5 0
6 2-3 5
6 0-1 7
5 6-7 1
5 4-5 7
5 2-3 5
5 0-1 7
4 6-7 1
4 4-5 7
4 2-3 5
4 0-1 7
3 6-7 1
3 4-5 6
3 2-3 5
3 0-1 7
2 6-7 2
2 4-5 7
2 2-3 3
2 0-1 7
1 6-7 2
1 4-5 7
1 2-3 3
1 0-1 7
0 6-7 4
0 4-5 4
0 2-3 3
0 0-1 7
หรือในรูปแบบตาราง
00005577
11775577
11775577
11665577
22773377
22773377
44443377
โปรดทราบว่าผู้เขียนใช้ null terminator สำหรับสองรายการแรกของตาราง (ส่อเสียด!)
สิ่งนี้ได้รับการออกแบบหลังจากแสดงผลเจ็ดส่วนโดยมี7
s เป็นช่องว่าง ดังนั้นรายการในตารางแรกจะต้องกำหนดกลุ่มที่สว่างขึ้น
ตารางแรก
__TIME__
เป็นแมโครพิเศษที่กำหนดโดยตัวประมวลผลล่วงหน้า มันจะขยายอย่างต่อเนื่องสตริงที่มีเวลาที่ preprocessor "HH:MM:SS"
ถูกเรียกใช้ในรูปแบบ สังเกตว่ามันมีตัวอักษรทั้งหมด 8 ตัว หมายเหตุที่ 0-9 มีค่า ASCII 48 ผ่าน 57 และ:
มีค่า ASCII 58 การส่งออกเป็น 64 ตัวอักษรต่อบรรทัดเพื่อให้ใบ 8 __TIME__
ตัวอักษรต่อตัวละคร
7 - i/8%8
ดังนั้นดัชนีของ__TIME__
ที่กำลังถูกส่งออกในปัจจุบัน ( 7-
จำเป็นเพราะเราทำซ้ำi
ลง) ดังนั้นt
เป็นลักษณะของ__TIME__
การส่งออก
a
จบลงด้วยการเท่ากับต่อไปนี้ในไบนารีขึ้นอยู่กับอินพุตt
:
0 00111111
1 00101000
2 01110101
3 01111001
4 01101010
5 01011011
6 01011111
7 00101001
8 01111111
9 01111011
: 01000000
แต่ละหมายเลขเป็นบิตแมปที่อธิบายถึงกลุ่มที่สว่างขึ้นในการแสดงผลเจ็ดส่วนของเรา เนื่องจากอักขระเป็น ASCII 7 บิตทั้งหมดบิตที่สูงจึงถูกล้างเสมอ ดังนั้น7
ในตารางเซ็กเมนต์จะพิมพ์เป็นค่าว่างเสมอ ตารางที่สองมีลักษณะเช่นนี้โดยมี7
s เป็นช่องว่าง:
000055
11 55
11 55
116655
22 33
22 33
444433
ตัวอย่างเช่น4
คือ01101010
(บิต 1, 3, 5 และ 6 ชุด) ซึ่งพิมพ์เป็น
----!!--
!!--!!--
!!--!!--
!!!!!!--
----!!--
----!!--
----!!--
เพื่อแสดงให้เห็นว่าเราเข้าใจโค้ดจริงๆแล้วให้ปรับเอาท์พุตเล็กน้อยด้วยตารางนี้:
00
11 55
11 55
66
22 33
22 33
44
"?;;?==? '::799\x07"
นี้จะถูกเข้ารหัสเป็น เพื่อจุดประสงค์ทางศิลปะเราจะเพิ่ม 64 ถึงอักขระบางส่วน (เนื่องจากใช้เพียงบิตต่ำ 6 บิตสิ่งนี้จะไม่ส่งผลกระทบต่อเอาต์พุต) สิ่งนี้จะช่วยให้"?{{?}}?gg::799G"
(โปรดทราบว่าตัวละครที่ 8 ไม่ได้ใช้งานดังนั้นเราสามารถทำมันได้ตามที่เราต้องการ) วางตารางใหม่ของเราในรหัสเดิม:
main(_){_^448&&main(-~_);putchar(--_%64?32|-~7[__TIME__-_/8%8][">'txiZ^(~z?"-48]>>"?{{?}}?gg::799G"[_*2&8|_/64]/(_&2?1:8)%8&1:10);}
เราได้รับ
!! !! !!
!! !! !! !! !! !! !! !! !!
!! !! !! !! !! !! !! !! !!
!! !! !! !!
!! !! !! !! !! !! !! !! !!
!! !! !! !! !! !! !! !! !!
!! !! !!
อย่างที่เราคาดไว้ มันไม่ได้ดูดีเหมือนต้นฉบับซึ่งอธิบายว่าทำไมผู้เขียนเลือกใช้ตารางที่เขาทำ
printf("%d", _);
ไปยังจุดเริ่มต้นของการmain
พิมพ์: pastebin.com/HHhXAYdJ