난독 화하자.
들여 쓰기 :
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
테이블 값 의 상위 8 진수 ( i%8
0,1,4,5) 또는 하위 8 진수 ( 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 종결자를 사용했습니다 (sneaky!).
이것은 7 세그먼트 디스플레이 후에 7
s를 공백으로 하여 설계되었습니다 . 따라서 첫 번째 테이블의 항목은 점등되는 세그먼트를 정의해야합니다.
첫 번째 테이블
__TIME__
전처리기에 의해 정의 된 특수 매크로입니다. 전처리 기가 실행 된 시간을 포함하는 문자열 상수로 확장됩니다 (형식) "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
각 숫자는 7 세그먼트 디스플레이에서 점등되는 세그먼트를 설명 하는 비트 맵 입니다. 문자는 모두 7 비트 ASCII이므로 높은 비트는 항상 지워집니다. 따라서 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