这段代码片段让我抓狂,有人可以帮我解释一下吗?
#include <stdio.h>
char*_="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";
int main(int l){for(l+=7;l!=putchar(010);++l);if(*(++_))main
(*_!=88?(putchar(*_^073)|putchar(33))&1:0xffff2a8b);}
谢谢,
Chan Nguyen
答案 0 :(得分:7)
为了理解此代码的工作原理,请以可读的方式重新编写代码:
#include <stdio.h>
char*_="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";
int main(int l)
{
for( l += 7; l != putchar(010); ++l ) {
}
if( *(++_) ) {
main( ( *_ != 88 ) ? ( putchar(*_^073) | putchar(33) )&1 : 0xffff2a8b );
}
return 0;
}
现在让我们理解它:
其参数l
(如果你运行没有参数的程序,它将为1)增加7(它变为8)
循环将打印010
(八进制8:ascii退格)直到l==8
(因此在运行程序时它不会执行任何操作
如果_
指向的下一个字符(现在是x
)不同于0(这可能意味着“直到我们到达_
”的结尾), main
被调用,但让我们看看在评估其参数时会发生什么:
_
当前指向的字符与88中的字符不同(ascii中88为x
),因此main的参数将是表达式( putchar(*_^073) | putchar(33) )&1
的结果:< / p>
在评估main
的参数时,将打印两个字符
第一个是:*_^073
,就是它,120^59
(因为x
是120,在ascii中,而八进制中的073是十进制的59),这是{ {1}}:120(67
)XOR 59(0b1000011
)= 67 0b111011
第二个是33(0b1000011
)
!
参数将是main
的结果,即1
如果您真的想了解细节中发生的事情,您将不得不继续这项工作,但是您将能够看到运行程序会发生什么(可能会在某处放置(67|33)&1
,这样你就可以看到输出了)。它会写一个反复的字符串“usleep(10000)
”。
编写这样的程序非常简单:一旦你决定你的算法是如何工作的,很容易生成一个字符串,比如Corsix!
,这会使算法生成你想要的,但是对它进行反向工程是一个更难。
答案 1 :(得分:4)
虽然这段代码不符合标准,但gcc会编译它,输出与我对代码的分析一致。可悲的是,如果没有更多的背景,我无法真正解释输出。如果我忽略退格,输出看起来像这样:
C!o!r!s!i!...
要分析代码,我们首先将它格式化一下:
#include <stdio.h>
char* _ ="XxTIHRCXCxTIHRXRCxTIHXHRCxTIXIHRCxTXTIHRCxXxTIHRCX";
int main(int l){
for(l+=7; l != putchar(010); ++l); // 010 = 8 -> backspace char
if(*(++_))
main(
*_ != 88 ? // *_ != 'X'
( putchar(*_ ^ 073) | putchar(33) ) & 1 : // 33 = '!'
0xffff2a8b);
}
在我们继续前进之前,有一些值得注意的事情:
现在注意,只要_指针被输出,它就会与八进制值073进行异或。如果我们将这个应用于整个字符串,我们得到:
cCorsixcxCorsicixCorscsixCorcrsixCocorsixCcCorsixc
这开始类似于我们之前看到的输出。让我们继续分析一些更有趣的路线:
for(l+=7; l != putchar(010); ++l); // 010 = 8 -> backspace char
这一行的目的是输出一系列退格。如果l等于1,则只输出一个退格。但是,如果它等于别的东西,它会在倾倒一辆卡车上变得狂暴起来。行为取决于主要的调用方式。在启动时,它似乎总是被调用值1(不知道为什么)。
现在让我们看一下递归主调用的组件。
( putchar(*_ ^ 073) | putchar(33) ) & 1 : // 33 = '!'
这是第一个可能的分支。首先它输出一个XORed字符,然后输出'!'焦炭。如果你看一下33的位模式,你会注意到(x | 33)&amp; 1将始终评估为1.因此在这种情况下,我们只在for循环中输出一个退格字符。
另一方面,第二个分支有点棘手,因为传递给main的值不是1.如果仔细查看程序的输出,您会注意到它确实在某个地方输出了卡车载荷的退格在字符串中。没有背景,我无法真正说出目标是什么。
现在我们已经完成了所有部分,让我们重写代码:
#include <stdio.h>
#define BIG_CONSTANT 42 // Not the actual value.
int main () {
char* str = "cCorsixcxCorsicixCorscsixCorcrsixCocorsixCcCorsixc";
putchar(8);
char* c = str;
while (*c != '\0') {
if (*c != 'c') { // 'X' ^ 073 = 'c'
putchar(*c);
putchar('!');
putchar(8);
}
else {
for (int i = 0; i < BIG_CONSTANT; ++i)
putchar(8);
}
c++;
}
}
我的C有点生疏,所以这可能无法编译/运行。它仍然可以让你很好地了解正在发生的事情。
编辑:我发布答案的时间有点晚了,我才刚刚意识到我的控制台正在打印退格,而不仅仅是删除字符。这就是为什么我有点误解了输出。就像接受的答案所说的那样,如果你真正正确地处理退格,它会打印出Corsix!。