免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 6401 | 回复: 23
打印 上一主题 下一主题

最混乱程序解析 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-07-31 18:42 |只看该作者 |倒序浏览
#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 %d\n"):9:16:t<0?t<-72?ma
in(_,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}eK
K{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);
}

论坛徽章:
0
2 [报告]
发表于 2007-07-31 18:44 |只看该作者

最混乱程序解析

1、代理整理

1 #include <stdio.h>
2 main(t,_,a)
3     char *a;
4 {
5    return
6    !0<t?
7        t<3?
8            main(-79,-13,a+main(-87,1-_,main(-86,0,a+1)+a)):
9            1,
10         t<_?
11             main(t+1,_,a):
12             3,
13         main(-94,-27+t,a)&&t==2?
14             _<13?
15                 main(2,_+1,"%s %d %d\n"):
16                 9:
17             16:
18       t<0?
19            t<-72?
20                main(_,t, "@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,"
21                          "/*{*+,/w{%+,/w#q#n+,/#{l+,/n{n+,/"
22                          "+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,"
23                          "}{w+K w'K:'+}e#';dq#'l q#'+d'K#!/"
24                          "+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n"
25                          "'){)#}w'){){nl]'/+#n';d}rw' i;# )"
26                          "{nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+"
27                          "'K {rw' iK{;[{nl]'/w#q#n'wk nw' i"
28                          "wk{KK{nl]!/w{%'l##w#' i; :{nl]'/*"
29                          "{q#'ld;r'}{nlwb!/*de}'c ;;{nl'-{}"
30                          "rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+"
31                          ";#'rdq#w! nr'/ ') }+}{rl#'{n' ')#"
32                          "}'+}##(!!/"):
33                t<-50?
34                    _==*a?
35                        putchar(31[a]):
36                        main(-65,_,a+1):
37                    main((*a=='/')+t,_,a+1):
38                0<t?
39                    main(2,2,"%s"):
40                    *a=='/'||main(0,main(-61,*a, "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry"),a+1);
41 }




程序使用问号表达式,逗号表达式,递归这些方式,配上比较麻烦的流程控制和参数控制来实现

第6行: !0<t?, !的优先级较高, 所以!0<t? 就是 1<t?
第9行: 最后是逗号,表明后面是逗号表达式
第12行: 最后是逗号,表明后面是逗号表达式
整理后, 如第14行_<13 ?这个问号表达式的两个值分别为main(2,_+1,"%s %d %d\n"); 和 9;
第13行, main(-94,-27+t,a) && t==2 先执行main, 再判断t==2
第40行, 也是如此, 先执行 *a=='/', 如果为真, 则不执行后面的main, 如果 *a!='/', 再执行后面的main.

补充两点:
a. main我们平时只用两个参数,实际是有三个,第三个参数为环境变量
b. 数组的使用, 一个数组array, 其表现形式 31[array] 与 array[31] 是一致的.

论坛徽章:
0
3 [报告]
发表于 2007-07-31 18:45 |只看该作者

最混乱程序解析

2、编码方式

我们看其中的两段字符串
SECTION A:
@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' ')#}'+}##(!!/


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


这两段的关系如何呢?

SECTION A是内容代码表, SECTION B是编码对照表
内容编码按照'/'作为分隔符分成若干段,搜索时,取出内容编码中的一个字符,在编码对照表中从左向右找到相应的字符,找到后,在编码对照表中按照相应的字符向后移31个字节,得到的字符就是最终要显示的字符。

SECTION A经SECTION B翻译后为:

On the /first/second/third/fourth/fifth/sixth/seventh/eigth/ninth/tenth/eleventh/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 per tree.

整理并编号

0、On the
-1、first
-2、second
-3、third
-4、fourth
-5、fifth
-6、sixth
-7、seventh
-8、eigth
-9、ninth
-10、tenth
-11、eleventh
-12、twelfth
-13、 day of Christmas my true love gave to me

-14、twelve drummers drumming,
-15、eleven pipers piping,
-16、ten lords a-leaping,

-17、nine ladies dancing,
-18、eight maids a-milking,
-19、seven swans a-swimming,

-20、six geese a-laying,
-21、five gold rings;

-22、four calling birds,
-23、three french hens,
-24、two turtle doves
    and(这个and是第24段中的内容)
-25、a partridge in a per tree.

可以发现,程序最后所打出的内容就是这26个段组合而成。

论坛徽章:
0
4 [报告]
发表于 2007-07-31 18:47 |只看该作者

最混乱程序解析

3、流程分析

这里主要分析这里t是怎么控制各部分入口, 以及各部分的功能.

SECTION A: t==1的时候,_没用, a没用, 程序启动的时候, 不要加参数, 这个时候t就会为1, 并且这个时候, 只能进入到 main(2,2,"%s")这里, 下一个控制就是 t==2

SECTION B: 2<=t<=13时, _为日期, _的范围是2-13
   在这里, t==2时, 打印 On the .... day of Christmas my true love gave to me
   如果t<_, 也就是t<日数的时候, t要嵌套自加, 直到与_相等
   当t与_相等后, 根据t打印第t-1天的礼物.
   打印完所有礼物, 再判断_<13, 如果成立, 则嵌套将_自加.
   这里是控制12天的方式.

SECTION C: t<-72 设置打印的段
   我们已经将内容解码为26个段, 并分别给出了编码, 我们的编号都是从0向下分直到-25, 因为程序里就是这样控制的.
   在这里, 有一个操作, main( _, t, .... ), 将_与t互换, 因为在进入这段控制之前, 都会将t设成小于-72的值, _设为要打印的段, 由于段-25<sec<0, 所以经过这样的互换, 下一次嵌套t就变成-25<sec<0这个范围中的数, 在这个程序里就只能进入-50<=t<0这个段之中.
   这里还有个关键操作, 是设置a, 也就是设置内容段.

SECTION D: -50<=t<0 查找内容段起始位置, 跳出条件为t=0
   也就是从t<-72之后, 就会进入此流程中, 如果t<0, 就会反复调用main((*a=='/')+t,_,a+1), 直到查找到指定的段. 这里的 *a=='/' 如果一段结束, 此表达式就为1, 则此语句就变成 main(1+t,_,a+1), 如果不为'/', 就成了main(t,_,a+1), 由于进入此段控制时, t是段值的相反数, 如-13, 所以在内容代码中要跳过12个段才能找到所需要打印的内容.直到t为0,并查找到起始地址a

SECTION E: t==0, 设置打印内容
   此时如果当前内容代码的第一个字符内容不为'/',则会调用后面的main(0,main(-61,*a,"...................."),a+1);
   这里的main(-61,*a,"!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m.vpbks,fxntdCeghiry")就是设置编码对照表.
   这里以前设置的内容代码表中段的超始位置a放到了_这个参数上, 然后将编码对照表也设置上.
   这个时候, 我们就拥有了 内容代码表要显示内容和编码对照表. 下面就是如何将它们显示出来.
   这里设置的-61, 也只能进入到 -72<=t<-50这个控制中.

SECTION F: -72<=t<-50, 查找编码对照表并显示字符
   进入到这个控制的时候, _是内容表中的内容, a则是编码对照表中的内容,要在a中查找到与_一样的字符.
   所以main(-65, _, a+1)就是这个作用, 这里的-65保证能进入到此控制中, 并且前面代码中_==*a保证如果_与*a一致了,就调用putchar(31[a]), 否则就会用main(-65,_,a+1)来查找编码对照表中的下一个字符.

SECTION G: 总结一下:
   如果想要打印某段内容, 入口就是 t<-72 , 也就是代码中-79, -87, -86, -94, 都是要打印的语句, 同时在打印的时候将第二个参数设置成段的索引值, 如打印第5段, 则将第二个参数设置为-5就可以了.

[ 本帖最后由 alfonso 于 2007-8-2 09:45 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2007-07-31 18:49 |只看该作者

最混乱程序解析

4、写这样一个程序

根据上面的分析, 我们可以将流程整理一下:


a. t==1:       程序入口,设置t=2,_=2

b. 2<=t<=13:
   t==2, 打印On the ..... day of Christmas my true love game me

   if(t<_) 将t加大到与_相同, step为1

   打印第t-1天的礼物;

   if( t==2 && _<13 )
      将_增加1

c. t<-72:      设置内容表, _为段索引
d. -50<=t:     查找内容段起始位置,跳出条件为t==0
e. -72<=t<-50: 在编码表中查找字符或打印,
f. t==0:       设置编码表

根据这个分析写个C语言程序:
当然这里如何变换成递归没详细写,但是大家应该能看得明白。


main(t,_,a)
char *a;
{
   /* 程序入口控制 */
   if( t==1 )
      main( 2, 2, a ); /* 这个时候a是没用的 */

   /* 控制日数及打印段 */
   if( t>=2 && t<=13 ) {  /* 在整个这一段, a都是没用的, 只有t与_有用 */
      if( t==2 ) {
         main( -90, 0, a );    /*打印第0段内容, 我们分析过了,只要t<-72就可以*/
         main( -90, 1-_, a );  /*这里 _-1 是日数, 所以 1-_ 表示内容代码中第几天这个段 */
         main( -90, -13, a );  /*打印第13段*/
      }

      if( t<_ )
         main( t+1, _, a );

      main( -90, -27+t, a );   /*这里打印第n天的礼物 */

      if( t==2 && _<13 )
         main( t, _+1, a );
   }

   /* 设置内容代码表 */
   if( 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' ')#}'+}##(!!/" );

   /* 查找内容段起始位置 */
   if( t>=-50 && t<0 ) {
      if( *a != '/' )
         main( t, _, a+1 );
      else
         main( t+1, _, a+1 );
   }

      /* 设置编码表 */
   if( t==0 ) {
      if( *a != '/' ) {
         /* 先设置, 再查找 */
         main( -70, *a, "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry" );
         main( 0, _, a+1 );
      }
   }

   /* 在编码表中查找字符或打印 */
   if( t>=-72 && t<-50 ) {
      if( _==*a )
         putchar( a[31] );
      else
         main( -60, _, a+1 );  /* 只要是-72与-50之间的数就可以 */
   }
}



上面程序就是按流程改写的程序, 可以通过整合, 并转换形成最初混乱的代码.
这个程序中的各个控制点的值都是可以自己设置的, 只要能保证流程走正确.

OVER

[ 本帖最后由 alfonso 于 2007-8-2 10:01 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2007-07-31 18:53 |只看该作者
qiang han

论坛徽章:
0
7 [报告]
发表于 2007-07-31 19:24 |只看该作者
不错不错~~~~~~~~~顶~~~~~

论坛徽章:
0
8 [报告]
发表于 2007-07-31 19:37 |只看该作者
我记得有一个程序可以把源代码风格变为GNU格式的。那个应该可以把混乱代码排成稍微能够看的懂的样子吧。嘿嘿

论坛徽章:
0
9 [报告]
发表于 2007-07-31 19:56 |只看该作者
这里的混乱不止是形式上的混乱,逻辑关系也复杂得很啊。

论坛徽章:
0
10 [报告]
发表于 2007-07-31 22:01 |只看该作者
这些对于建立和谐社会没有任何意义..
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP