如何加密/混亂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);
}

程序到這里應該差不多了。還是那句話——“每一個程序員都有把源代碼弄復雜的潛質”,大家好自為之。

轉自:http://coolshell.cn/articles/933.html

原創文章,作者:s19930811,如若轉載,請注明出處:http://www.www58058.com/2261

(0)
s19930811s19930811
上一篇 2016-05-07 14:52
下一篇 2016-05-09 19:43

相關推薦

  • 第二十一周作業

    1、回顧并詳細總結MySQL的存儲引擎、索引; 常用存儲引擎的對比: 特點 MyISAM InnoDB MEMORY MERGE NDB 存儲限制 有 64TB 有 沒有 有 事務安全 支持 鎖機制 表鎖 行鎖 表鎖 表鎖 行鎖 B樹索引 支持 支持 支持 支持 支持 哈希索引 支持 全文索引 支持 集群索引 支持 數據緩存 支持 支持 支持 索引緩存 支持…

    2017-07-19
  • linux發展歷程簡述

     linux發展歷程簡述 概述       本文寫的linux 的發展歷史,閱讀本文你可以知道:           1.   linux的發音           2. &nbs…

    Linux干貨 2016-10-14
  • Linux用戶組管理

    馬哥網絡教育21期+第三周練習 用戶及用戶組 用戶配置文件     用戶:UID,/etc/passwd     組:GID,/etc/group 密碼配置文件     用戶:/etc/shadow    &n…

    Linux干貨 2016-09-02
  • Linux網絡配置基礎二(網絡模塊與nmcli命令)

    Linux網絡配置基礎二 相關命令 lsmod命令 lsmod命令用于顯示已經加載到內核中的模塊的狀態信息。執行lsmod命令后會列出所有已載入系統的模塊。Linux操作系統的核心具有模塊化的特性,應此在編譯核心時,務須把全部的功能都放入核心。您可以將這些功能編譯成一個個單獨的模塊,待需要時再分別載入。第一列:表示模塊的名稱第二列:表示模塊的大小第三列:表示…

    Linux干貨 2016-09-09
  • Linux下find命令的使用

    為什么要使用find命令?     Linux系統中有著成千上萬的文件,如果你想要找到自己想要的文件,一款查找軟件是必不可少的,而locate是根據其生成的數據庫進行查找,雖然速度會略快,但非實時查找,有些新的文件或目錄是匹配不到的,而且locate是模糊匹配,而find命令為實時查找,且為精確匹配,如果你對目錄的權限…

    Linux干貨 2016-08-18
  • vim文本編輯器

    vim簡介: vi: Visual Interface,文本編輯器 文本:ASCII, Unicode 文本編輯種類: 行編輯器: sed 全屏編輯器:nano, vi vim – Vi Improved 其他編輯器: gedit一個簡單的圖形編輯器 gvim一個Vim 編輯器的圖形版本   vim使用: 三種主要模式: 命令(Norm…

    Linux干貨 2017-06-17
欧美性久久久久