一个C语言程序求分析
main(_){_^448&&main(-~_);putchar(--_%64?32|-~7[__TIME__-_/8%8][">'txiZ^(~z?"-48]>>";;;====~$::199"[_*2&8|_/64]/(_&2?1:8)%8&1:10);} 展开
分析一:这个程序的输入是变量"_",因为标准C中是允许下划线开头的变量的,仅有下划线也满足变量命名的要求;
分析二:双下划线"__"这里不能理解为变量,我猜测"__TIME__"是C语言中的一个宏定义,是一个整体;
分析三:断句。仔细从“乱码”中能一眼看出两个关键字"main"和"putchar"。main函数里面居然还有main?!对,没错,这是一个递归函数。
把在分号后面添加回车,假如适量缩进,并把"_"用"argc"代替。程序的主要结构大致如下:
main(argc)
{
argc^448 && main(-~argc);
putchar(
--argc%64?32|-~7[__TIME__-argc/8%8][">'txiZ^(~z?"-48]>>";;;====~$::199"[argc*2&8|argc/64]/(argc&2?1:8)%8&1:10
);
}
分析四:如何实现的递归?没有返回值,没有if-else语句,怎么能递归,这貌似是不太可能的事,但是仔细分析一下第一句,即"_^448 && main(-~_);"
这是一个"condition1 && condition2"条件运算语句,如果condition1和condition2同为真(true),则该语句为真(true),否则,只要有一个condition为假(false),则该语句为假。C语言为了提高效率,如果condition1为假,程序是不会再去运算condition2的,很明显,在condition1 == 0时无论condition2是真是假,结果都是假。所以当"argc^448"的值为0时,递归结束。
递归就实现了。
分析五:putchar(*&^%$##$^^&***&^%&)。
putchar()函数不用多讲,是最简单的函数了,其作用就是输出一个ascii码对应的字符,例如要输出"a",只需写putchar('a');即可。所以可以推测putchar两个小括号之间应该是某个字符对应的ascii码。
根据C语言运算符的优先级结合性再对代码进行断句:
main(argc)
{
argc^448&&main(-~argc);
putchar(
--argc%64
?
(32|-~7[__TIME__-argc/8%8][">'txiZ^(~z?"-48] >> ";;;====~$::199"[argc*2&8|argc/64]/(argc&2?1:8)%8&1)
:
10
);
}
我特意把"condition ? value1 : value2"这个三目运算符写的非常明显,楼主可看懂?
其实这个三目运算符就是相当与一个if-else语句,这条putchar()语句和下面的是等效的:
if(--argc % 64)
putchar(32|-~7[__TIME__-argc/8%8][">'txiZ^(~z?"-48] >> ";;;====~$::199"[argc*2&8|argc/64]/(argc&2?1:8)%8&1);
else
putchar(10);
如果楼主不信,可以将刚刚的代码替换原来的putchar一句,你会发现结果是一致的。
分析六:到此时,最复杂的东西就是第一个putchar的内容。其实根据运算符的优先级和结合性来分析的话,第一个putchar里的内容有下面几块:
32 | -~
7[__TIME__-argc/8%8][">'txiZ^(~z?"-48]
>>
";;;====~$::199"[argc*2&8|argc/64]/(argc&2?1:8)%8
&
1
咋一看,有几个中括号若隐若现,于是想到了数组,但是却没发现有数组名,难道是错觉吗?!
如果楼主对数组与指针非常熟悉的话就应该知道,其实数组名就是一个地址,而地址就是一个特定含义的数字罢了。
所以"7"是一个地址;
";;;====~$::199"也是一个地址
第一个地址非常好理解,就是第7号地址
第二个其实也非常直观,就是字符串";;;====~$::199"在内存中的地址。你可以定义一个全局变量如下:
char *str = ";;;====~$::199";
然后再代码中用str代替";;;====~$::199",结果是一致的。
现在将这两个地址的“带入原来的putchar语句中(怎么有点解方程的意思……)得:
32
|
-~ 7[A][B] >> str[C] / D % 8
&
1
其中
A = __TIME__-argc/8%8
B = ">'txiZ^(~z?"-48
C = argc*2&8|argc/64
D = argc&2?1:8
=================================================
好,分析先告一段落,我们来吧代码重新整理一下
#define A (__TIME__-argc/8%8)
#define B (">'txiZ^(~z?"-48)
#define C (argc*2&8|argc/64)
#define D (argc&2?1:8)
char *str = ";;;====~$::199";
main(argc)
{
if(argc^448)
main(-~argc);
if(--argc%64)
{
putchar(32|-~ (7[A][B]) >> str[C]/D%8&1);
}
else
putchar(10);
}
怎么样,是不是看起来规范了一点呢^_^,最重要的是运行结果和之前的完全匹配
=================================================
结论:
我觉得我已经把代码整理得够清晰的了,至于"__TIME__"是什么?第7号地址是什么?以及宏定义B中的">'txiZ^(~z?"有何特殊意义楼主还是自己去查查资料吧,相信弄懂后你会对C语言的具体实现过程有非常深刻的了解的。
有疑问百度hi给我留言,虽然我不能保证及时答复,但只要是我知道的我一定会回答的
如果楼主喜欢这种怪异的C代码,我推荐下面几个例子,包爽!
http://coolshell.cn/articles/914.html
http://coolshell.cn/articles/933.html
最后,这个程序输出的是该可执行文件的修改时间。对于这个程序的设计者,我表示深深地膜拜!!
参考资料: 原创