如何加密/混乱C源代码
之前发表了《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); }
程序到这里应该差不多了。还是那句话——“每一个程序员都有把源代码弄复杂的潜质”,大家好自为之。
(转载本站文章请注明作者和出处 酷 壳 – CoolShell ,请勿用于任何商业用途)
《如何加密/混乱C源代码》的相关评论
哈哈,有意思…
恩,果然很混乱~
每次接手经过前辈们几番修改的代码,我都会深深的感受“每一个程序员都有把源代码弄复杂的潜质”中的潜质已经淋漓尽致的变成了现实:不需要经过这么多复杂的替换,程序已经自然复杂到剪不断理还乱,横看成岭侧成峰,让人无法识别真面目的境地了!-_-
呵呵 取消临时变量不错
呵呵,唯恐世界不乱
文章排版有问题了,代码全部丢失了。
@WindyWinter
对不起,不知道什么原因,现在修复了。
@耗子
(___ / __) <= _____)
我汗
原来程序还能这样写
长见识了
果然有意思..可以唬人
世界真疯狂~
太TMD有才了
stack overflow error
果然有潜质!!!
但是最后那个变态程序输出只有前面几个是素数…………..
要想读懂这代码,很简单! 先编译好,再查看反汇编代码,嘿嘿…..
@arose616
聪明!
太好玩了!!
由于重构工具的存在,第五步是没有太大意义的
眼睛打架 脑袋抽筋
我也来一个,交换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;
第一个程序,怎么25是素数呢?
最后一句是正确的,以前我很少给程序写注释,结果是我最后看不懂我自己写的程序了。
牛b!~“每一个程序员都有把源代码弄复杂的潜质”
点睛之笔
那个printf(“%dt”… 是不是应该是printf(“%d\t”… 啊!?
我觉得一般了……
有一个基于这个的辗转相除法
while(a%=b^=a^=b^=a);
这个很赞
@Tydus
大赞!!!
见识了
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 }
第七行的j*j<i应该为j*j<=i结果才对
还可以这样搞啊! 向楼主学习啦! 呵呵 好东西
违背了编程的风格
….太牛了
错误代码 for(j = 2; j * j <= i; ++j) 这样才是对的,25也会被纳入素数
能把人看疯了,用来整人不错
这是混淆的思路么?
呵呵,试了一下最后一个代码,跑出来结果有点问题哈,至少是没有97
哈哈
真乱,哈哈哈