我是C的新手,我急切地想知道这段代码有什么神奇之处?
int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\
o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}
可在此处找到来源:http://www.ioccc.org/1984/anonymous.c
以下是代码附带的提示:
不光彩的提及: 匿名
作者太尴尬了他/她可以写这样的垃圾,所以 我答应保护自己的身份。我会说是作者 该程序与C编程有着众所周知的联系 语言。这个程序是古老的“你好, 世界“程序。读取的内容可能就像写一样! 版权所有(c)1984,Landon Curt Noll。版权所有。允许 个人,教育或非营利用途均予以批准 此版权和通知全文包含在内并保留 不变。所有其他用途必须事先获得书面许可 来自Landon Curt Noll和Larry Bassel。
答案 0 :(得分:13)
当你有一个混淆代码时,你需要清理物理布局,添加一些空格,添加必要的缩进,然后编译代码。编译器的警告会告诉你很多程序隐藏的东西。
首先简化 - 添加空格
int i;
main()
{
for( ; i["]<i;++i){--i;}"];
read('-'-'-', i+++"hell\o, world!\n", '/'/'/'));
}
read(j,i,p)
{
write(j/p+p,i---j,i/i);
}
当使用gcc -Wall
编译程序时,我收到以下警告:
soc.c:2:1: warning: return type defaults to ‘int’ [enabled by default]
main()
^
soc.c: In function ‘main’:
soc.c:4:4: warning: implicit declaration of function ‘read’ [-Wimplicit-function-declaration]
for( ; i["]<i;++i){--i;}"]; read('-'-'-', i+++"hell\o, world!\n", '/'/'/'));
^
soc.c:4:50: warning: unknown escape sequence: '\o' [enabled by default]
for( ; i["]<i;++i){--i;}"]; read('-'-'-', i+++"hell\o, world!\n", '/'/'/'));
^
soc.c: At top level:
soc.c:7:1: warning: return type defaults to ‘int’ [enabled by default]
read(j,i,p)
^
soc.c: In function ‘read’:
soc.c:7:1: warning: type of ‘j’ defaults to ‘int’ [enabled by default]
soc.c:7:1: warning: type of ‘i’ defaults to ‘int’ [enabled by default]
soc.c:7:1: warning: type of ‘p’ defaults to ‘int’ [enabled by default]
soc.c:9:4: warning: implicit declaration of function ‘write’ [-Wimplicit-function-declaration]
write(j/p+p,i---j,i/i);
^
soc.c:9:17: warning: operation on ‘i’ may be undefined [-Wsequence-point]
write(j/p+p,i---j,i/i);
^
soc.c:9:17: warning: operation on ‘i’ may be undefined [-Wsequence-point]
soc.c:10:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
第二次削减简化 - 取消混淆
根据上述警告,该程序可以不加以模糊:
int i;
void read(int j, char* i, int p);
void write(int j, char* i, int p);
int main()
{
for( ; i["]<i;++i){--i;}"];
read('-'-'-', , '/'/'/'));
return 0;
}
void read(int j, char* i, int p)
{
write(j/p+p, (i--) - j, 1);
}
上述版本没有编译器警告并产生相同的输出。
第三次削减简化 - 取消混淆
表达式i["]<i;++i){--i;}"]
用于运行循环14次。就那么简单。它可以简化为i < 14
。
'-'-'-'
是0
。
'/'/'/'
是1
。
i++ + "hello, world!\n"
与s + i++
相同,其中s
可以是char const* s = "hello, world!\n";
for
循环可以简化为:
char const* s = "hello, world!\n";
for( ; i < 14; read(0, s+i++, 1));
由于j
中read
的值始终为零,因此read
的实现可以简化为:
void read(int j, char* i, int p)
{
write(0, (i--), 1);
}
表达式(i--)
可以简化为i
,因为作为副作用递减不会改变函数的运算。换句话说,上述功能是:
void read(int j, char* i, int p)
{
write(0, i, 1);
}
当我们意识到参数j
的值始终为0
且参数p
的值始终为1
时,我们可以更改for
循环在main函数中:
for( ; i < 14; i++)
{
write(0, s+i, 1);
}
因此,整个程序可以简化为:
void write(int j, char const* i, int p);
int main()
{
int i = 0;
char const* s = "hello, world!\n";
for( ; i < 14; i++ )
{
write(0, s+i, 1);
}
return 0;
}
第四次简化 - 简化
以上版本的硬编码为14
。这是s
中的字符数。因此,通过将程序更改为:
void write(int j, char const* i, int p);
int main()
{
write(0, "hello, world!\n", 14);
return 0;
}
答案 1 :(得分:2)
让我们重写代码,替换一些表达式并添加注释
int i; // i = 0 by default
main()
{
for( ;
"]<i;++i){--i;}" [i]; // magic: it is the same as i["]<i;++i){--i;}"];
// the important part is that there's 14 chars in the
// string, same length that "hello, world!\n"
// the content of the string has no importance here,
// in the end 'i' will go from 0 to 14
read(0, // since '-' - '-' is equal to 0,
"hello, world!\n" + (i++), // same as i+++"hello, world!\n"
// it is pointers arythmetic
// the second arg to the read
// function defined further points
// to the letter to print
1)) // '/' / '/' division result is 1
;
}
// the read function is then always called with
// j == 0
// i is a pointer to the char to print
// p == 1
// And for the obfuscation fun, the read function will write something :)
read(j,i,p)
{
write(0, // j/p+p is equal to 0, which is the stdout
i, // i-- - j is equal to i, decrement of i comes later
1); // i / i is equal to 1, this means one char to print
}