Этот код печатает карту Индии. Как это работает?
#include <stdio.h>
main()
{
int a,b,c;
int count = 1;
for (b=c=10;a="- FIGURE?, UMKC,XYZHello Folks,\
TFy!QJu ROo TNn(ROo)SLq SLq ULo+\
UHs UJq TNn*RPn/QPbEWS_JSWQAIJO^\
NBELPeHBFHT}TnALVlBLOFAkHFOuFETp\
HCStHAUFAgcEAelclcn^r^r\\tZvYxXy\
T|S~Pn SPm SOn TNn ULo0ULo#ULo-W\
Hq!WFs XDt!" [b+++21]; )
for(; a-- > 64 ; )
putchar ( ++c=='Z' ? c = c/ 9:33^b&1);
return 0;
}
c
obfuscation
narayanpatra
источник
источник
Ответы:
Длинная строка - это просто двоичная последовательность, преобразованная в ASCII. Первый
for
операторb
начинается с 10, а[b+++21]
после строки возвращается 31. Обрабатывая строку как массив, смещение 31 является началом «реальных» данных в строке (вторая строка в предоставленном вами примере кода). Остальная часть кода просто перебирает последовательность битов, конвертируя 1 и 0 в! И пробелы и печатая по одному символу за раз.Менее запутанная версия:
Странноумная часть вputchar
отчетности. Возьми первыйputchar
. ASCII'Z'
- это 90 в десятичном виде, поэтому 90/9 = 10, что является символом новой строки. Во втором десятичное 33 является ASCII для'!'
. Переключение младшего бита 33 дает 32, что является ASCII для пробела. Это приводит!
к печати, еслиb
она нечетная, и пустому пространству для печати, еслиb
она четная. Остальная часть кода просто для того, чтобы пройти «указатель»a
через строку.источник
По сути, строка представляет собой кодировку длины строки : чередующиеся символы в строке говорят, сколько раз рисовать пробел и сколько раз подряд восклицательный знак. Вот анализ различных элементов этой программы:
Кодированная строка
Первые 31 символ этой строки игнорируются. Остальные содержат инструкции по рисованию изображения. Отдельные символы определяют, сколько пробелов или восклицательных знаков можно нарисовать последовательно.
Наружный для петли
Этот цикл перебирает символы в строке. Каждая итерация увеличивает значение
b
на единицу и присваивает следующий символ в строкеa
.Внутренний цикл
Этот цикл рисует отдельные символы и символ новой строки всякий раз, когда он достигает конца строки. Количество символов обращено это
a - 64
. Значениеc
изменяется от 10 до 90 и сбрасывается до 10 при достижении конца строки.putchar
Это может быть переписано как:
Он рисует соответствующий символ, в зависимости от того,
b
является ли он четным или нечетным, или перевод строки, когда это необходимо.источник
b
начинается с 10, а индекс(b++)+21
начинается с 31.