首页 > C/C++语言, 编程语言, 轶事趣闻 > 如何加密/混乱C源代码

如何加密/混乱C源代码

2009年5月30日 发表评论 阅读评论 26,656 人阅读    

之前发表了《6个变态的C语言Hello World程序》[酷壳链接] [CSDN链接],主要是是像大家展示了一些C语言的变态玩法。也向大家展示了一下程序是可以写得让人看不懂的,在那篇文章中,可以看到很多人的留言,很多人都觉得很好玩,是的,那本来是用来供朋友们“消遣作乐”,供娱乐娱东而已,不必太过认真。

不过,通过这种极端的写法,大家可以看到源代码都可以写得那么复杂难懂的。大家也许在赞叹之余一笑了之,而我则希望,大家能够在娱乐以后认真思考一下,你不要以为咱们自己不会把代码搞得那么复杂,只不过没有像那6个Hello World一样那么极端,不过,说句老实话,咱们每个程序都有把清晰的程序搞得一团混乱的潜能,只不过程度不一样罢了,我并不是在这里危言耸听,大家好自为之

下面是一个Step by Step的教程,教你如何把一个清晰的代码变得复杂难懂的。当然,这只是一个“简明教程”了。还是那句话——“本文仅供朋友们“消遣作乐”,如果你要觉得有意思的话,顶个贴。如果你觉得没什么意思的话,一笑了之。仅供娱乐而已,不必太过认真。

开始程序

下面是一个找出素数的程序:

void primes(int cap)
{
    int i, j, composite;

    for(i = 2; i < cap; ++i) {
        composite = 0;
        for(j = 2; j * j < i; ++j) {
            composite += !(i % j);
        }
        if(!composite){
            printf("%dt", i);
        }
    }
}

int main()
{
    primes(100);
}

下面我们来看看如何把上面这段代码搞得复杂难懂。

第一步、把for变成while

通常来说,for循坏要以while循坏简单一些,上面的程序有二重for循环,我们不但要把其变成while循环,而且还要把二重循环的变成一重的循环,然后使用大量的if-else语句来判断。

void primes(int cap)
{
    int i, j, composite, t = 0;

    while(t < cap * cap) {
        i = t / cap;
        j = t++ % cap;
        if(i <= 1);
        else if(!j)
            composite = j;
        else if(j == i && !composite)
            printf("%dt",i);
        else if(j > 1 && j < i)
            composite += !(i % j);
    }
}

int main()
{
    primes(100);
}

第二步,把循坏变成递归

递归在某些时候是可以把代码变得简单,但大多数的情况下是把代码变得复杂,而且很没有效率。下面是把上面的while循环变成了递归。变成了递归后,函数的参数都变成3个了。

void primes(int cap, int t, int composite)
{
    int i,j;
    i = t / cap;
    j = t % cap;
    if(i <= 1)
        primes(cap,t+1,composite);
    else if(!j)
        primes(cap,t+1,j);
    else if(j == i && !composite)
        (printf("%dt",i), primes(cap,t+1,composite));
    else if(j > 1 && j < i)
        primes(cap,t+1, composite + !(i % j));
    else if(t < cap * cap)
        primes(cap,t+1,composite);
}

int main()
{
    primes(100,0,0);
}

第三步,弄乱代码结构/使用没有含义的变量名

关于如何弄乱代码结构,其中一个小技巧是,使用“?”表达式代替if-else语句。

void primes(int m, int t, int c)
{
    int i,j;
    i = t / m;
    j = t % m;
    (i <= 1) ? primes(m,t+1,c) : (!j) ? primes(m,t+1,j) : (j == i && !c) ?
    (printf("%dt",i), primes(m,t+1,c)) : (j > 1 && j < i) ?
    primes(m,t+1,c + !(i % j)) : (t < m * m) ? primes(m,t+1,c) : 0;
}

int main()
{
    primes(100,0,0);
}

第四步,取消临时变量

临时变量一般用来保存反复使用的一个表达式的值。使用大量重复的表达式来取消这些临时变量的也可以让代码复杂起来。

void primes(int m, int t, int c)
{
  ((t / m) <= 1) ? primes(m,t+1,c) : !(t % m) ? primes(m,t+1, t % m) :
  ((t % m)==(t / m) && !c) ? (printf("%dt",(t / m)), primes(m,t+1,c)) :
  ((t % m)> 1 && (t % m) < (t / m)) ? primes(m,t+1,c + !((t / m) % (t % m))) :
  (t < m * m) ? primes(m,t+1,c) : 0;
}

int main()
{
    primes(100,0,0);
}

第五步,继续弄乱变量名

我们知道,下划线是合法的变量名,所以,我们不妨用__,___,____来代替m,t,c。函数名也可以使用下划线来代替。让我们来看看求素数的函数能变成什么。

void _(int __, int ___, int ____)
{
    ((___ / __) <= 1) ? _(__,___+1,____) : !(___ % __) ? _(__,___+1,___ % __) :
    ((___ % __)==(___ / __) && !____) ? (printf("%dt",(___ / __)),
    _(__,___+1,____)) : ((___ % __) > 1 && (___ % __) < (___ / __)) ?
    _(__,___+1,____ + !((___ / __) % (___ % __))) : (___ < __ * __) ?
    _(__,___+1,____) : 0;
}

int main()
{
    _(100,0,0);
}

第六步,移除常量

在上面的程序中,还有一些常量,你可以通过增加一个宏定义,或是增加一个函数的形参来取代这一常量。

void _(int __, int ___, int ____, int _____)
{
    ((___ / __) <= _____) ? _(__,___+_____,____,_____) : !(___ % __) ? _(__,___+_____,___ % __, _____) :
    ((___ % __)==(___ / __) && !____) ? (printf("%dt",(___ / __)),
    _(__,___+_____,____,_____)) : ((___ % __) > _____ && (___ % __) < (___ / __)) ?
    _(__,___+_____,____,_____ + !((___ / __) % (___ % __))) : (___ < __ * __) ?
    _(__,___+_____,____,_____) : 0;
}

int main() {
    _(100,0,0,1);
}

程序到这里应该差不多了。还是那句话——“每一个程序员都有把源代码弄复杂的潜质”,大家好自为之。





好烂啊有点差凑合看看还不错很精彩 (60 人打了分,平均分: 4.73 )
Loading ... Loading ...
  1. 2009年5月30日16:18 | #1

    哈哈,有意思…

  2. 2009年5月31日09:11 | #2

    恩,果然很混乱~

  3. 2009年5月31日10:56 | #3

    每次接手经过前辈们几番修改的代码,我都会深深的感受“每一个程序员都有把源代码弄复杂的潜质”中的潜质已经淋漓尽致的变成了现实:不需要经过这么多复杂的替换,程序已经自然复杂到剪不断理还乱,横看成岭侧成峰,让人无法识别真面目的境地了!-_-

  4. youthgun
    2009年6月8日20:34 | #4

    呵呵 取消临时变量不错

  5. ss
    2009年7月30日22:34 | #5

    呵呵,唯恐世界不乱

  6. 2009年11月9日11:43 | #6

    文章排版有问题了,代码全部丢失了。

  7. 2009年11月9日13:00 | #7

    @WindyWinter
    对不起,不知道什么原因,现在修复了。

  8. 2009年11月12日22:38 | #8

    @耗子
    (___ / __) &lt;= _____)

  9. 焚琴煮鹤
    2009年11月23日20:34 | #9

    我汗
    原来程序还能这样写
    长见识了

  10. Lshine
    2009年12月5日20:05 | #10

    果然有意思..可以唬人

  11. 飘过狂人
    2009年12月5日23:08 | #11

    世界真疯狂~

  12. 2009年12月5日23:36 | #12

    太TMD有才了

  13. viggin
    2009年12月17日17:29 | #13

    stack overflow error

  14. wjn-nb
    2009年12月20日11:29 | #14

    果然有潜质!!!

  15. - -!
    2009年12月22日00:22 | #15

    但是最后那个变态程序输出只有前面几个是素数…………..

  16. arose616
    2009年12月24日13:36 | #16

    要想读懂这代码,很简单! 先编译好,再查看反汇编代码,嘿嘿…..

  17. jor
    2009年12月24日16:17 | #17

    @arose616
    聪明!

  18. commander118
    2010年1月2日13:29 | #18

    太好玩了!!

  19. ADAS
    2010年1月27日10:38 | #19

    由于重构工具的存在,第五步是没有太大意义的

  20. 古歌
    2010年1月28日16:30 | #20

    眼睛打架 脑袋抽筋

  21. 2010年2月22日17:29 | #21

    我也来一个,交换A,B的值通常这样写:int T=A; A=B; B=T;为了混乱可以这样写:A=A+B; B=A-B; A=A-B; 也可以这样写:A=A^B; B=A^B; A=A^B;

  22. guy
    2010年5月13日22:15 | #22

    第一个程序,怎么25是素数呢?

  23. 2010年5月14日21:41 | #23

    最后一句是正确的,以前我很少给程序写注释,结果是我最后看不懂我自己写的程序了。

  24. 路人甲
    2010年5月19日22:56 | #24

    牛b!~“每一个程序员都有把源代码弄复杂的潜质”
    点睛之笔

  25. onion
    2010年6月3日03:35 | #25

    那个printf(“%dt”… 是不是应该是printf(“%d\t”… 啊!?

  26. Tydus
    2010年6月16日08:49 | #26

    我觉得一般了……

    道法自然 :
    我也来一个,交换A,B的值通常这样写:int T=A; A=B; B=T;为了混乱可以这样写:A=A+B; B=A-B; A=A-B; 也可以这样写:A=A^B; B=A^B; A=A^B;

    有一个基于这个的辗转相除法
    while(a%=b^=a^=b^=a);
    这个很赞

  27. 少林旋龟
    2010年6月24日15:17 | #27

    @Tydus
    大赞!!!

  28. elaine
    2010年7月20日09:40 | #28

    见识了

  29. lxk
    2010年7月22日12:13 | #29

    void primes(int cap)

    02 {

    03 int i, j, composite;

    04

    05 for(i = 2; i < cap; ++i) {

    06 composite = 0;

    07 for(j = 2; j * j < =i; ++j) {

    08 composite += !(i % j);

    09 }

    10 if(!composite){

    11 printf("%dt", i);

    12 }

    13 }

    14 }

    15

    16 int main()

    17 {

    18 primes(100);

    19 }

  30. lxk
    2010年7月22日12:14 | #30

    第七行的j*j<i应该为j*j<=i结果才对

  31. xty_seven
    2010年10月9日17:48 | #31

    还可以这样搞啊! 向楼主学习啦! 呵呵 好东西

  32. luweb
    2011年1月27日20:21 | #32

    lxk :
    第七行的j*j<i应该为j*j<=i结果才对

  33. seesee
    2011年4月24日21:03 | #33

    违背了编程的风格

  34. xinranmsn
    2011年5月7日17:58 | #34

    ….太牛了

  35. Ban
    2011年5月27日01:23 | #35

    错误代码 for(j = 2; j * j <= i; ++j) 这样才是对的,25也会被纳入素数

  36. Benhuan
    2011年6月4日08:36 | #36

    能把人看疯了,用来整人不错

  37. 2011年6月13日12:49 | #37

    这是混淆的思路么?

  38. Topro
    2011年7月4日01:39 | #38

    呵呵,试了一下最后一个代码,跑出来结果有点问题哈,至少是没有97

  39. 2011年8月5日22:37 | #39

    arose616 :
    要想读懂这代码,很简单! 先编译好,再查看反汇编代码,嘿嘿…..

    哈哈

  40. ebert
    2011年8月23日18:51 | #40

    真乱,哈哈哈

  41. 2011年10月4日13:48 | #41

    我自己以前就经常走到第一步和第二步 咩哈哈哈

  42. 2011年11月1日17:17 | #42

    好强大啊

  43. 2011年11月11日20:47 | #43

    貌似最后一个得到素数有点少了~~

  44. guyson
    2011年12月21日13:19 | #44

    完全崩溃了。

  45. 狂且
    2011年12月30日20:05 | #45

    凌乱了!!

  46. 2012年2月4日10:07 | #46

    太牛了啊,高手

  1. 2009年6月2日09:29 | #1
  2. 2009年11月11日13:29 | #2
  3. 2010年8月31日17:24 | #3
  4. 2011年5月16日00:14 | #4
  5. 2011年5月24日15:51 | #5
  6. 2011年5月27日14:49 | #6
  7. 2011年6月3日09:31 | #7
  8. 2011年6月5日10:48 | #8
  9. 2011年6月20日16:48 | #9
  10. 2011年7月9日03:08 | #10
  11. 2011年12月21日23:16 | #11

无觅相关文章插件,快速提升流量