C 混淆的科学计算器。请解释一下它是如何工作的
我试图理解下面的程序是如何工作的。它是一个命令行科学计算器。来源于。对于IOCCC条目来说,它看起来相当可读,但显然不是C 混淆的科学计算器。请解释一下它是如何工作的,c,obfuscation,C,Obfuscation,我试图理解下面的程序是如何工作的。它是一个命令行科学计算器。来源于。对于IOCCC条目来说,它看起来相当可读,但显然不是 #include <stdio.h> #include <math.h> #define clear 1;if(c>=11){c=0;sscanf(_,"%lf%c",&r,&c);while(*++_-c);}\ else if(argc>=4&&!main(4-(*_++=='('),argv))_+
#include <stdio.h>
#include <math.h>
#define clear 1;if(c>=11){c=0;sscanf(_,"%lf%c",&r,&c);while(*++_-c);}\
else if(argc>=4&&!main(4-(*_++=='('),argv))_++;g:c+=
#define puts(d,e) return 0;}{double a;int b;char c=(argc<4?d)&15;\
b=(*_%__LINE__+7)%9*(3*e>>c&1);c+=
#define I(d) (r);if(argc<4&&*#d==*_){a=r;r=usage?r*a:r+a;goto g;}c=c
#define return if(argc==2)printf("%f\n",r);return argc>=4+
#define usage main(4-__LINE__/26,argv)
#define calculator *_*(int)
#define l (r);r=--b?r:
#define _ argv[1]
#define x
double r;
int main(int argc,char** argv){
if(argc<2){
puts(
usage: calculator 11/26+222/31
+~~~~~~~~~~~~~~~~~~~~~~~~calculator-\
! 7.584,367 )
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
! clear ! 0 ||l -x l tan I (/) |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
! 1 | 2 | 3 ||l 1/x l cos I (*) |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
! 4 | 5 | 6 ||l exp l sqrt I (+) |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+
! 7 | 8 | 9 ||l sin l log I (-) |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(0
);
}
return 0;
}
有人能解释一下它是如何工作的吗?它扩展成这样:
double r;
int
main (int argc, char **argv)
{
if (argc < 2)
{
if (argc == 2)
printf ("%f\n", r);
return argc >= 4 + 0;
}
{
double a;
int b;
char c = (argc < 4 ? main (4 - 21 / 26,
argv) : *argv[1] * (int) 11 / 26 + 222 / 31 +
~~~~~~~~~~~~~~~~~~~~~~~~*argv[1] * (int) -!7.584) & 15;
b = (*argv[1] % 21 + 7) % 9 * (3 * 367 >> c & 1);
c += +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+!1;
if (c >= 11)
{
c = 0;
sscanf (argv[1], "%lf%c", &r, &c);
while (*++argv[1] - c);
}
else if (argc >= 4 && !main (4 - (*argv[1]++ == '('), argv))
argv[1]++;
g:c += !0 || (r);
r = --b ? r : -(r);
r = --b ? r : tan (r);
if (argc < 4 && *"/" == *argv[1])
{
a = r;
r = main (4 - 23 / 26, argv) ? r * a : r + a;
goto g;
}
c = c | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+!1 | 2 | 3 || (r);
r = --b ? r : 1 / (r);
r = --b ? r : cos (r);
if (argc < 4 && *"*" == *argv[1])
{
a = r;
r = main (4 - 25 / 26, argv) ? r * a : r + a;
goto g;
}
c = c | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+!4 | 5 | 6 || (r);
r = --b ? r : exp (r);
r = --b ? r : sqrt (r);
if (argc < 4 && *"+" == *argv[1])
{
a = r;
r = main (4 - 27 / 26, argv) ? r * a : r + a;
goto g;
}
c = c | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+!7 | 8 | 9 || (r);
r = --b ? r : sin (r);
r = --b ? r : log (r);
if (argc < 4 && *"-" == *argv[1])
{
a = r;
r = main (4 - 29 / 26, argv) ? r * a : r + a;
goto g;
}
c = c | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(0);
}
if (argc == 2)
printf ("%f\n", r);
return argc >= 4 + 0;
}
它仍然不是完全可读的,但至少现在没有什么是对你隐藏的。你应该能够做你的简化,而不会被咬得那么厉害
@cmaster说:“出于同样的原因,我不打算进行完整的解释。研究这段源代码的预处理形式,也许可以使用gcc-C-E obfusc.C | grep-v'^'| indent>obfusc。然后我查看了里面的̀obfusc.I肯定不会。IOCCC条目需要我至少两个小时来分析,我会在试图理解它的功能的过程中完全重构代码,而冗长的解释可能需要一天的时间来编写,并且完全超出了本网站IMHO的范围。请注意_LINE__u宏,它对换行非常敏感。它用于标识/*+-运算符。
double r;
int
main (int argc, char **argv)
{
if (argc < 2)
{
if (argc == 2)
printf ("%f\n", r);
return argc >= 4 + 0;
}
{
double a;
int b;
char c = (argc < 4 ? main (4 - 21 / 26,
argv) : *argv[1] * (int) 11 / 26 + 222 / 31 +
~~~~~~~~~~~~~~~~~~~~~~~~*argv[1] * (int) -!7.584) & 15;
b = (*argv[1] % 21 + 7) % 9 * (3 * 367 >> c & 1);
c += +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+!1;
if (c >= 11)
{
c = 0;
sscanf (argv[1], "%lf%c", &r, &c);
while (*++argv[1] - c);
}
else if (argc >= 4 && !main (4 - (*argv[1]++ == '('), argv))
argv[1]++;
g:c += !0 || (r);
r = --b ? r : -(r);
r = --b ? r : tan (r);
if (argc < 4 && *"/" == *argv[1])
{
a = r;
r = main (4 - 23 / 26, argv) ? r * a : r + a;
goto g;
}
c = c | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+!1 | 2 | 3 || (r);
r = --b ? r : 1 / (r);
r = --b ? r : cos (r);
if (argc < 4 && *"*" == *argv[1])
{
a = r;
r = main (4 - 25 / 26, argv) ? r * a : r + a;
goto g;
}
c = c | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+!4 | 5 | 6 || (r);
r = --b ? r : exp (r);
r = --b ? r : sqrt (r);
if (argc < 4 && *"+" == *argv[1])
{
a = r;
r = main (4 - 27 / 26, argv) ? r * a : r + a;
goto g;
}
c = c | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+!7 | 8 | 9 || (r);
r = --b ? r : sin (r);
r = --b ? r : log (r);
if (argc < 4 && *"-" == *argv[1])
{
a = r;
r = main (4 - 29 / 26, argv) ? r * a : r + a;
goto g;
}
c = c | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(0);
}
if (argc == 2)
printf ("%f\n", r);
return argc >= 4 + 0;
}