2013年6月28日 alex

又看到有人引用了那段难懂的C代码,简单说两句

#include <stdio.h>
main(t,_,a)
char *a;
{
return!0<t?t<3?main(-79,-13,a+main(-87,1-_,main(-86,0,a+1)+a)):1,t<_?main(t+1,_,a):3,main(-94,-27+t,a)&&t==2?_<13?
main(2,_+1,”%s %d %dn”):9:16:t<0?t<-72?main(_,t,
“@n’+,#’/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l+,/n{n+,/+#n+,/#
;#q#n+,/+k#;*+,/’r :’d*’3,}{w+K w’K:’+}e#’;dq#’l
q#’+d’K#!/+k#;q#’r}eKK#}w’r}eKK{nl]’/#;#q#n’){)#}w’){){nl]’/+#n’;d}rw’ i;#
){nl]!/n{n#’; r{#w’r nc{nl]’/#{l,+’K {rw’ iK{;[{nl]’/w#q#n’wk nw’
iwk{KK{nl]!/w{%’l##w#’ i; :{nl]’/*{q#’ld;r’}{nlwb!/*de}’c
;;{nl’-{}rw]’/+,}##’*}#nc,’,#nw]’/+kd’+e}+;#’rdq#w! nr’/ ‘) }+}{rl#'{n’ ‘)#
}’+}##(!!/”)
:t<-50?_==*a?putchar(31[a]):main(-65,_,a+1):main((*a==’/’)+t,_,a+1)
:0<t?main(2,2,”%s”):*a==’/’||main(0,main(-61,*a,
“!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:nuwloca-O;m .vpbks,fxntdCeghiry”),a+1);
}

这段C代码的阅读可以考验读者作为地球人的毅力哈哈,是以前世界最难懂C代码比赛的一段代码~当时我看了好久才隐约明白过来~ 最近看到有博友发了这个,简单分析两句~
这段代码之所以难以理解主要是因为 1)尽可能的利用递归,2)分明就是只有putchar输出字符而已,却故意把字符串搞成很难阅读,3)把逻辑分支都搞成问号冒号的形式。。。分解的第一步自然是把绕眼的字符串先砍掉。

去掉双引号的部分先分析逻辑
双引号故意乱眼的部分是:
“@n’+,#’/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l+,/n{n+,/+#n+,/#
;#q#n+,/+k#;*+,/’r :’d*’3,}{w+K w’K:’+}e#’;dq#’l
q#’+d’K#!/+k#;q#’r}eKK#}w’r}eKK{nl]’/#;#q#n’){)#}w’){){nl]’/+#n’;d}rw’ i;#
){nl]!/n{n#’; r{#w’r nc{nl]’/#{l,+’K {rw’ iK{;[{nl]’/w#q#n’wk nw’
iwk{KK{nl]!/w{%’l##w#’ i; :{nl]’/*{q#’ld;r’}{nlwb!/*de}’c
;;{nl’-{}rw]’/+,}##’*}#nc,’,#nw]’/+kd’+e}+;#’rdq#w! nr’/ ‘) }+}{rl#'{n’ ‘)#
}’+}##(!!/”

“!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:nuwloca-O;m .vpbks,fxntdCeghiry”

去掉以后,把问号冒号和递归逻辑展开,这里比较麻烦,因为实在套了不少。
但先不用展,我们也能分析一些东西。我们知道,要控制递归结束,嵌套执行的次数运气好的话会在程序里找到常数。暂且假设作者没有变态到连这个控制用的数都隐藏起来了,试着从表面查找它。程序中大小比较只有“<”,查找所有的“<”,发现变量和常数比较的时候出现的正数只有13,又因为程序中没有出现递减1,但有很多递加1,可以感觉到,貌似是循环13或12次输出什么东西,而具体输出的东西自然应该和那两段乱人眼的引号之间的字符串有关系,因为连续重复的字符貌似没太有,所以可以暂时先试着排除作者要输出某种字符组成的图形的可能性,往后再展开程序具体分析那两段怎么变成正常的地球语言~ 有空的朋友可以具体分析下哈~ 不过感觉这个过程比较需要耐心~

运行结果是:

On the first day of Christmas my true love gave to me
a partridge in a pear tree.

On the second day of Christmas my true love gave to me
two turtle doves
and a partridge in a pear tree.

On the third day of Christmas my true love gave to me
three french hens, two turtle doves
and a partridge in a pear tree.

On the fourth day of Christmas my true love gave to me
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the fifth day of Christmas my true love gave to me
five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the sixth day of Christmas my true love gave to me
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the seventh day of Christmas my true love gave to me
seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the eigth day of Christmas my true love gave to me
eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the ninth day of Christmas my true love gave to me
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the tenth day of Christmas my true love gave to me
ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the eleventh day of Christmas my true love gave to me
eleven pipers piping, ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

On the twelfth day of Christmas my true love gave to me
twelve drummers drumming, eleven pipers piping, ten lords a-leaping,
nine ladies dancing, eight maids a-milking, seven swans a-swimming,
six geese a-laying, five gold rings;
four calling birds, three french hens, two turtle doves
and a partridge in a pear tree.

有了结果,规则基本可以看见了,再倒回去分析可能会容易一些。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

刚才我在网上搜了一下这段文字,发现有人把这段程序解析成地球版本了已经~
以下程序来自这里

///////////////////////////////////////////////////////////////////////
//"!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:nuwloca-O;m .vpbks,fxntdCeghiry";
// !-------------------------------!
///////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////
//
// @n'+,#'
// on the
//---------------------------------------------------------------------
// /*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l,+,/n{n+,/+#n+,/#;#q#n+,/+k#;*+,/
//  first second third fourth fifth sixth seventh eighth ninth tenth eleventh twelfth
//---------------------------------------------------------------------
//  'r :'d*'3,}{w+K w'K:'+}e#';dq#'l q#'+d'K#!
//   day of Christmas my true love gave to me
//---------------------------------------------------------------------
// /+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# ){nl]!
//  twelve drummers drumming,  eleven pipers piping,  ten lords a-leaping,
//---------------------------------------------------------------------
// /n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' iwk{KK{nl]!
//  nine ladies dancing,  eight maids a-milking,  seven swans a-swimming,
//---------------------------------------------------------------------
// /w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlw]!
//  six geese a-laying,  five gold rings,
//---------------------------------------------------------------------
// /*de}'c ;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w!
//  four calling birds,  three french hens,  two turtle doves
//---------------------------------------------------------------------
//   nr'/ ') }+}{rl#'{n' ')# }'+}##(!!/
//  and  a partridge in a pear tree.
//
///////////////////////////////////////////////////////////////////////

#include <stdio.h>

#ifdef __TURBOC__
#include <conio.h>
#endif

#define END_DAY     12
#define START_DAY    1

#if !(START_DAY>0&&END_DAY<=12&&START_DAY<=END_DAY)
    #error "error! START_DAY or END_DAY is not in range!"
#endif

const int START_DELIMITERS   =  0;
const int NUMBERS_DELIMITERS = 13;
const int GIFTS_DELIMITERS   = 13;

const char * decodeTbl=
"!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:nuwloca-O;m .vpbks,fxntdCeghiry";
const char * cryptograph=
"@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l+,/n{n+,/+#n+,/#
;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l 
q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# 
){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' 
iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlw]!/*de}'c 
;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')# 
}'+}##(!!/";

void decodeAndPrint(int d)
{
    const char *pc = cryptograph;

    while (d < 0)
    {
        if (*pc++ == '/')
        {
            d++;
        }
    }

    while (*pc != '/')
    {
        const char *p = decodeTbl;
        while (*p != *pc) p++;
        putchar(p[31]);
        pc++;
    }
}

void start()
{
    decodeAndPrint( - START_DELIMITERS );
}

void number(int n)
{
    decodeAndPrint( - (START_DELIMITERS+n) );
}

void dayToMe()
{
    decodeAndPrint( - (START_DELIMITERS+NUMBERS_DELIMITERS) );
}

void gift(int g)
{
    decodeAndPrint( g - (START_DELIMITERS+NUMBERS_DELIMITERS+GIFTS_DELIMITERS) );
}

void gifts(int g, int n)
{
    if (g < n)
        gifts(g + 1, n);
    if (g > 0)
        gift(g);
}

void printBible(int n)
{
#ifdef __TURBOC__
    static int temp = 0;
    if(++temp%5==0)
        getch();
#endif
    start();
    number(n);
    dayToMe();
    gifts(1, n);
    if( n < END_DAY)
        printBible(n + 1);
}

void main()
{
#ifdef __TURBOC__
    clrscr();
#endif
    printBible(START_DAY);
#ifdef __TURBOC__
    getch();
#endif
}