如何加密/混亂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  :https://coolshell.cn/articles/933.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章