Об оформлении
кода
программ можно спорить бесконечно,
одни пишут так, другие этак. Однако сегодня
мы поговорим о том, как оформлять код
неправильно, как намеренно сделать его
менее читаемым. По научному это называется
обфускацией, однако в данном случае это не
обфускация в прямом понимании, а лишь
действительно затруднение понимания. Так
или иначе некоторые приемы могут оказаться
достаточно действенными и полезными и в
простом кодинге, так что область их
применения я готов оставить на твое
усмотрение.

Прежде всего поговорим о простых вещах. Ну
например - внешний вид. Не надо делать
структурированные и хорошо выглядящие
программы, в них каждый за 5 минут
разберется и исправит все, убрав твое
авторство. Сделай свою программу похожей на
произведение ASCII арта и всем будет приятно -
изучающим код прежде всего. Дальше -
переменные. Не надо их называть логически,
nWeight или  result сразу расскажет врагу о
работе твоей программы, используй
однобуквенные обозначения, причем
выработай свою схему, отличную от
общепринятой, ну прекрати наконец
использовать i для счетчика в цикле! Можешь
использовать несколько одинаково
называющихся переменных в разных участках
кода или присвоить одной переменной
несколько  имен и осуществлять их
ротацию. В названии функций будь абстрактен
и оперируй общими словами типа stuff, everything, this
и т.д. Как я уже говорил можно
переопределять переменные внутри разных
участков кода, например какой будет
результат у следующей программы:

int с = 26, d = 1;

{
int с = 69;
d += с;
}

printf("%d\t%d\n", с, d);

Кто первый ответит получит 2 WMZ... 🙂 Можно
так же использовать слияние двух
переменных в одной простой операцией:

unsigned int с = 150, d = 931;
unsigned long long merge = 0;

merge = c << sizeof(c) + d;

Что получится в итоге? Переменная "с"
разместится в первых 32 битах, а "b" в
последних 32 битах 64-битной переменной "merge".
Этот метод можно расширить для целых 16-битных
чисел и 8-битных символов.

Перейдем к ходу выполнения программы.
Можно сказать, что понимание работы
программы в большей степени зависит от
понимания хода ее выполнения. Поэтому
особое внимание следует уделить обфускации
алгоритма. Например, ради экономии кода и
эффективности обращайте прямые циклы в
убывающие, вот так например:

for(i = 0; i < limit; i++)
{
(...)
}

в 

int i = limit;
while(i--)

или

while(--i)

Ради приличия позаботьтесь так же о
развертывании возможных циклов. Например:

for(i = 0; i < 3; i++)
{
sum += inрut[i];
}

легко преобразовать в:

sum += input[0];
sum += input[1];
sum += input[2];

Или в более простую строчку:

sum += inрut[0] + input[1] + input[2];

Если цикл слишком велик для такого
раскладывания, можно сделать так:

for(i = 0; i < limit; i += 3) { sum += inрut[i]
+ inрut[i + 1] + inрut[i + 2]; }

Простой и эффективный способ запутать
читающего, согласитесь?

С функциями тоже можно поиграться, сведя
возможные из них к малопонятным строкам.
Например такую функцию 

int foo(int a, int b) 
{
a = а - b; 
b++;
a = а * b;

return a;
}

гораздо эффективнее определить так:

#define foo(а, b) ((а - b++) * (а * b))

Без боязни внедряйте излишний код или
кодовые ловушки. Помните о различии = и == в С?
Наверняка, ну а кто с первого раза поймет
такой пример?

if(a = 2) b++;

Кто правильно скажет результат? А вот
такой пример?

b ^= b;
if(b) а = ++с;

Он никогда не выполнится, все ведь это
сразу поняли, не так ли?

  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    0 комментариев
    Межтекстовые Отзывы
    Посмотреть все комментарии